diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pango-layout-private.h | 1 | ||||
-rw-r--r-- | pango/pango-layout.c | 291 | ||||
-rw-r--r-- | pango/pango-tabs.c | 133 | ||||
-rw-r--r-- | pango/pango-tabs.h | 35 | ||||
-rw-r--r-- | pango/serializer.c | 40 |
5 files changed, 413 insertions, 87 deletions
diff --git a/pango/pango-layout-private.h b/pango/pango-layout-private.h index b9f9b137..74c36126 100644 --- a/pango/pango-layout-private.h +++ b/pango/pango-layout-private.h @@ -74,6 +74,7 @@ struct _PangoLayout PangoRectangle logical_rect; PangoRectangle ink_rect; int tab_width; /* Cached width of a tab. -1 == not yet calculated */ + gunichar decimal; int copy_end; diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 7b32eeef..473d1785 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -82,6 +82,7 @@ #include "pango-glyph-item.h" #include <string.h> #include <math.h> +#include <locale.h> #include <hb-ot.h> @@ -225,6 +226,7 @@ pango_layout_init (PangoLayout *layout) layout->line_count = 0; layout->tab_width = -1; + layout->decimal = 0; layout->unknown_glyphs_count = -1; layout->wrap = PANGO_WRAP_WORD; @@ -1017,7 +1019,8 @@ pango_layout_get_alignment (PangoLayout *layout) * * Note that tabs and justification conflict with each other: * Justification will move content away from its tab-aligned - * positions. + * positions. The same is true for alignments other than + * %PANGO_ALIGN_LEFT. */ void pango_layout_set_tabs (PangoLayout *layout, @@ -3261,6 +3264,7 @@ pango_layout_line_leaked (PangoLayoutLine *line) *****************/ static void shape_tab (PangoLayoutLine *line, + ParaBreakState *state, PangoItem *item, PangoGlyphString *glyphs); @@ -3366,54 +3370,58 @@ ensure_tab_width (PangoLayout *layout) } } -/* For now we only need the tab position, we assume - * all tabs are left-aligned. - */ -static int -get_tab_pos (PangoLayout *layout, - int index, - gboolean *is_default) +static void +get_tab_pos (PangoLayoutLine *line, + int index, + int *tab_pos, + PangoTabAlign *alignment, + gunichar *decimal, + gboolean *is_default) { - gint n_tabs; + PangoLayout *layout = line->layout; + int n_tabs; gboolean in_pixels; + int offset = 0; + + if (layout->alignment != PANGO_ALIGN_CENTER) + { + if (line->is_paragraph_start && layout->indent >= 0) + offset = layout->indent; + else if (!line->is_paragraph_start && layout->indent < 0) + offset = - layout->indent; + } if (layout->tabs) { n_tabs = pango_tab_array_get_size (layout->tabs); in_pixels = pango_tab_array_get_positions_in_pixels (layout->tabs); - if (is_default) - *is_default = FALSE; + *is_default = FALSE; } else { n_tabs = 0; in_pixels = FALSE; - if (is_default) - *is_default = TRUE; + *is_default = TRUE; } if (index < n_tabs) { - gint pos = 0; - - pango_tab_array_get_tab (layout->tabs, index, NULL, &pos); + pango_tab_array_get_tab (layout->tabs, index, alignment, tab_pos); if (in_pixels) - return pos * PANGO_SCALE; - else - return pos; - } + *tab_pos *= PANGO_SCALE; - if (n_tabs > 0) + *decimal = pango_tab_array_get_decimal_point (layout->tabs, index); + } + else if (n_tabs > 0) { - /* Extrapolate tab position, repeating the last tab gap to - * infinity. - */ + /* Extrapolate tab position, repeating the last tab gap to infinity. */ int last_pos = 0; int next_to_last_pos = 0; int tab_width; - pango_tab_array_get_tab (layout->tabs, n_tabs - 1, NULL, &last_pos); + pango_tab_array_get_tab (layout->tabs, n_tabs - 1, alignment, &last_pos); + *decimal = pango_tab_array_get_decimal_point (layout->tabs, n_tabs - 1); if (n_tabs > 1) pango_tab_array_get_tab (layout->tabs, n_tabs - 2, NULL, &next_to_last_pos); @@ -3427,22 +3435,21 @@ get_tab_pos (PangoLayout *layout, } if (last_pos > next_to_last_pos) - { - tab_width = last_pos - next_to_last_pos; - } + tab_width = last_pos - next_to_last_pos; else - { - tab_width = layout->tab_width; - } + tab_width = layout->tab_width; - return last_pos + tab_width * (index - n_tabs + 1); + *tab_pos = last_pos + tab_width * (index - n_tabs + 1); } else { - /* No tab array set, so use default tab width - */ - return layout->tab_width * index; + /* No tab array set, so use default tab width */ + *tab_pos = layout->tab_width * index; + *alignment = PANGO_TAB_LEFT; + *decimal = 0; } + + *tab_pos -= offset; } static int @@ -3459,7 +3466,7 @@ line_width (PangoLayoutLine *line) { PangoLayoutRun *run = l->data; - for (i=0; i < run->glyphs->num_glyphs; i++) + for (i = 0; i < run->glyphs->num_glyphs; i++) width += run->glyphs->glyphs[i].geometry.width; } @@ -3483,14 +3490,33 @@ showing_space (const PangoAnalysis *analysis) return FALSE; } +static void break_state_set_last_tab (ParaBreakState *state, + PangoGlyphString *glyphs, + int width, + int tab_pos, + PangoTabAlign tab_align, + gunichar tab_decimal); + +static void +ensure_decimal (PangoLayout *layout) +{ + if (layout->decimal == 0) + layout->decimal = g_utf8_get_char (localeconv ()->decimal_point); +} + static void shape_tab (PangoLayoutLine *line, + ParaBreakState *state, PangoItem *item, PangoGlyphString *glyphs) { int i, space_width; + int current_width; + int tab_pos; + PangoTabAlign tab_align; + gunichar tab_decimal; - int current_width = line_width (line); + current_width = line_width (line); pango_glyph_string_set_size (glyphs, 1); @@ -3498,6 +3524,7 @@ shape_tab (PangoLayoutLine *line, glyphs->glyphs[0].glyph = PANGO_GET_UNKNOWN_GLYPH ('\t'); else glyphs->glyphs[0].glyph = PANGO_GLYPH_EMPTY; + glyphs->glyphs[0].geometry.x_offset = 0; glyphs->glyphs[0].geometry.y_offset = 0; glyphs->glyphs[0].attr.is_cluster_start = 1; @@ -3508,15 +3535,17 @@ shape_tab (PangoLayoutLine *line, ensure_tab_width (line->layout); space_width = line->layout->tab_width / 8; - for (i=0;;i++) + for (i = 0; ; i++) { gboolean is_default; - int tab_pos = get_tab_pos (line->layout, i, &is_default); + + get_tab_pos (line, i, &tab_pos, &tab_align, &tab_decimal, &is_default); + /* Make sure there is at least a space-width of space between - * tab-aligned text and the text before it. However, only do + * tab-aligned text and the text before it. However, only do * this if no tab array is set on the layout, ie. using default - * tab positions. If use has set tab positions, respect it to - * the pixel. + * tab positions. If the user has set tab positions, respect it + * to the pixel. */ if (tab_pos >= current_width + (is_default ? space_width : 1)) { @@ -3524,6 +3553,14 @@ shape_tab (PangoLayoutLine *line, break; } } + + if (tab_decimal == 0) + { + ensure_decimal (line->layout); + tab_decimal = line->layout->decimal; + } + + break_state_set_last_tab (state, glyphs, current_width, tab_pos, tab_align, tab_decimal); } static inline gboolean @@ -3607,12 +3644,69 @@ struct _ParaBreakState int hyphen_width; /* How much space a hyphen will take */ GList *baseline_shifts; + + PangoGlyphString *last_tab; + int last_tab_width; + int last_tab_pos; + PangoTabAlign last_tab_align; + gunichar last_tab_decimal; }; +static void +break_state_set_last_tab (ParaBreakState *state, + PangoGlyphString *glyphs, + int width, + int tab_pos, + PangoTabAlign tab_align, + gunichar tab_decimal) +{ + + state->last_tab = glyphs; + state->last_tab_width = width; + state->last_tab_pos = tab_pos; + state->last_tab_align = tab_align; + state->last_tab_decimal = tab_decimal; +} + static gboolean should_ellipsize_current_line (PangoLayout *layout, ParaBreakState *state); +static void +get_decimal_prefix_width (PangoItem *item, + PangoGlyphString *glyphs, + const char *text, + gunichar decimal, + int *width, + gboolean *found) +{ + PangoGlyphItem glyph_item = { item, glyphs, 0, 0, 0 }; + int *log_widths; + int i; + const char *p; + + log_widths = g_new (int, item->num_chars); + + pango_glyph_item_get_logical_widths (&glyph_item, text, log_widths); + + *width = 0; + *found = FALSE; + + for (i = 0, p = text + item->offset; i < item->num_chars; i++, p = g_utf8_next_char (p)) + { + if (g_utf8_get_char (p) == decimal) + { + *width += log_widths[i] / 2; + *found = TRUE; + break; + } + + *width += log_widths[i]; + } + + g_free (log_widths); +} + static PangoGlyphString * shape_run (PangoLayoutLine *line, ParaBreakState *state, @@ -3622,7 +3716,7 @@ shape_run (PangoLayoutLine *line, PangoGlyphString *glyphs = pango_glyph_string_new (); if (layout->text[item->offset] == '\t') - shape_tab (line, item, glyphs); + shape_tab (line, state, item, glyphs); else { PangoShapeFlags shape_flags = PANGO_SHAPE_NONE; @@ -3660,6 +3754,33 @@ shape_run (PangoLayoutLine *line, glyphs->glyphs[0].geometry.x_offset += space_left; glyphs->glyphs[glyphs->num_glyphs - 1].geometry.width += space_right; } + + if (state->last_tab != NULL) + { + int w; + + g_assert (state->last_tab->num_glyphs == 1); + + /* Update the width of the current tab to position this run properly */ + + w = state->last_tab_pos - state->last_tab_width; + + if (state->last_tab_align == PANGO_TAB_RIGHT) + w -= pango_glyph_string_get_width (glyphs); + else if (state->last_tab_align == PANGO_TAB_CENTER) + w -= pango_glyph_string_get_width (glyphs) / 2; + else if (state->last_tab_align == PANGO_TAB_DECIMAL) + { + int width; + gboolean found; + + get_decimal_prefix_width (item, glyphs, layout->text, state->last_tab_decimal, &width, &found); + + w -= width; + } + + state->last_tab->glyphs[0].geometry.width = MAX (w, 0); + } } return glyphs; @@ -3680,19 +3801,45 @@ insert_run (PangoLayoutLine *line, run->glyphs = glyphs; else if (last_run && state->log_widths_offset == 0 && !(run_item->analysis.flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN)) - run->glyphs = state->glyphs; + { + run->glyphs = state->glyphs; + state->glyphs = NULL; + } else run->glyphs = shape_run (line, state, run_item); - if (last_run) + if (last_run && state->glyphs) { - if (state->log_widths_offset > 0) - pango_glyph_string_free (state->glyphs); + pango_glyph_string_free (state->glyphs); state->glyphs = NULL; } line->runs = g_slist_prepend (line->runs, run); line->length += run_item->length; + + if (state->last_tab && run->glyphs != state->last_tab) + { + /* Adjust the tab position so placing further runs will continue to + * maintain the tab placement. In the case of decimal tabs, we are + * done once we've placed the run with the decimal point. + */ + + if (state->last_tab_align == PANGO_TAB_RIGHT) + state->last_tab_width += pango_glyph_string_get_width (run->glyphs); + else if (state->last_tab_align == PANGO_TAB_CENTER) + state->last_tab_width += pango_glyph_string_get_width (run->glyphs) / 2; + else if (state->last_tab_align == PANGO_TAB_DECIMAL) + { + int width; + gboolean found; + + get_decimal_prefix_width (run->item, run->glyphs, line->layout->text, state->last_tab_decimal, &width, &found); + + state->last_tab_width += width; + if (found) + state->last_tab = NULL; + } + } } static gboolean @@ -3800,6 +3947,20 @@ compute_log_widths (PangoLayout *layout, pango_glyph_item_get_logical_widths (&glyph_item, layout->text, state->log_widths); } +/* If last_tab is set, we've added a tab and remaining_width has been updated to + * account for its origin width, which is last_tab_pos - last_tab_width. shape_run + * updates the tab width, so we need to consider the delta when comparing + * against remaining_width. + */ +static int +tab_width_change (ParaBreakState *state) +{ + if (state->last_tab) + return state->last_tab->glyphs[0].geometry.width - (state->last_tab_pos - state->last_tab_width); + + return 0; +} + /* Tries to insert as much as possible of the item at the head of * state->items onto @line. Five results are possible: * @@ -3915,7 +4076,6 @@ process_item (PangoLayout *layout, if (state->remaining_width < 0 && !no_break_at_end) /* Wrapping off */ { insert_run (line, state, item, NULL, TRUE); - DEBUG1 ("no wrapping, all-fit"); return BREAK_ALL_FIT; } @@ -3931,6 +4091,16 @@ process_item (PangoLayout *layout, width += state->log_widths[state->log_widths_offset + i]; } + if (layout->text[item->offset] == '\t') + { + insert_run (line, state, item, NULL, TRUE); + state->remaining_width -= width; + state->remaining_width = MAX (state->remaining_width, 0); + + DEBUG1 ("tab run, all-fit"); + return BREAK_ALL_FIT; + } + if (!no_break_at_end && can_break_at (layout, state->start_offset + item->num_chars, wrap)) { @@ -3945,31 +4115,32 @@ process_item (PangoLayout *layout, else extra_width = 0; - if ((width + extra_width <= state->remaining_width || (item->num_chars == 1 && !line->runs)) && + if ((width + extra_width <= state->remaining_width || (item->num_chars == 1 && !line->runs) || + (state->last_tab && state->last_tab_align != PANGO_TAB_LEFT)) && !no_break_at_end) { + PangoGlyphString *glyphs; + DEBUG1 ("%d + %d <= %d", width, extra_width, state->remaining_width); - insert_run (line, state, item, NULL, FALSE); + glyphs = shape_run (line, state, item); - width = pango_glyph_string_get_width (((PangoGlyphItem *)(line->runs->data))->glyphs); + width = pango_glyph_string_get_width (glyphs) + tab_width_change (state); if (width + extra_width <= state->remaining_width || (item->num_chars == 1 && !line->runs)) { + insert_run (line, state, item, glyphs, TRUE); + state->remaining_width -= width; state->remaining_width = MAX (state->remaining_width, 0); - /* We passed last_run == FALSE to insert_run, so it did not do this */ - pango_glyph_string_free (state->glyphs); - state->glyphs = NULL; - DEBUG1 ("early accept '%.*s', all-fit, remaining %d", item->length, layout->text + item->offset, state->remaining_width); return BREAK_ALL_FIT; } - /* if it doesn't fit after shaping, revert and proceed to break the item */ - uninsert_run (line); + /* if it doesn't fit after shaping, discard and proceed to break the item */ + pango_glyph_string_free (glyphs); } /*** From here on, we look for a way to break item ***/ @@ -4054,7 +4225,7 @@ retry_break: glyphs = shape_run (line, state, new_item); - new_break_width = pango_glyph_string_get_width (glyphs); + new_break_width = pango_glyph_string_get_width (glyphs) + tab_width_change (state); if (num_chars > 0 && layout->log_attrs[state->start_offset + num_chars - 1].is_white) @@ -4315,6 +4486,10 @@ process_line (PangoLayout *layout, state->remaining_width = -1; else state->remaining_width = state->line_width; + + state->last_tab = NULL; + state->last_tab_align = PANGO_TAB_LEFT; + DEBUG ("starting to fill line", line, state); while (state->items) diff --git a/pango/pango-tabs.c b/pango/pango-tabs.c index c126ec91..27ae3be8 100644 --- a/pango/pango-tabs.c +++ b/pango/pango-tabs.c @@ -28,12 +28,9 @@ typedef struct _PangoTab PangoTab; struct _PangoTab { - gint location; /* Offset in pixels of this tab stop - * from the left margin of the text. - */ - PangoTabAlign alignment; /* Where the tab stop appears relative - * to the text. - */ + int location; + PangoTabAlign alignment; + gunichar decimal_point; }; /** @@ -42,7 +39,8 @@ struct _PangoTab * A `PangoTabArray` contains an array of tab stops. * * `PangoTabArray` can be used to set tab stops in a `PangoLayout`. - * Each tab stop has an alignment and a position. + * Each tab stop has an alignment, a position, and optionally + * a character to use as decimal point. */ struct _PangoTabArray { @@ -59,6 +57,7 @@ init_tabs (PangoTabArray *array, gint start, gint end) { array->tabs[start].location = 0; array->tabs[start].alignment = PANGO_TAB_LEFT; + array->tabs[start].decimal_point = 0; ++start; } } @@ -141,6 +140,7 @@ pango_tab_array_new_with_positions (gint size, array->tabs[0].alignment = first_alignment; array->tabs[0].location = first_position; + array->tabs[0].decimal_point = 0; if (size == 1) return array; @@ -155,6 +155,7 @@ pango_tab_array_new_with_positions (gint size, array->tabs[i].alignment = align; array->tabs[i].location = pos; + array->tabs[i].decimal_point = 0; ++i; } @@ -266,9 +267,6 @@ pango_tab_array_resize (PangoTabArray *tab_array, * @location: tab location in Pango units * * Sets the alignment and location of a tab stop. - * - * @alignment must always be %PANGO_TAB_LEFT in the current - * implementation. */ void pango_tab_array_set_tab (PangoTabArray *tab_array, @@ -278,7 +276,6 @@ pango_tab_array_set_tab (PangoTabArray *tab_array, { g_return_if_fail (tab_array != NULL); g_return_if_fail (tab_index >= 0); - g_return_if_fail (alignment == PANGO_TAB_LEFT); g_return_if_fail (location >= 0); if (tab_index >= tab_array->size) @@ -398,10 +395,21 @@ pango_tab_array_to_string (PangoTabArray *tab_array) for (int i = 0; i < tab_array->size; i++) { if (i > 0) - g_string_append_c (s, ' '); + g_string_append_c (s, '\n'); + + if (tab_array->tabs[i].alignment == PANGO_TAB_RIGHT) + g_string_append (s, "right:"); + else if (tab_array->tabs[i].alignment == PANGO_TAB_CENTER) + g_string_append (s, "center:"); + else if (tab_array->tabs[i].alignment == PANGO_TAB_DECIMAL) + g_string_append (s, "decimal:"); + g_string_append_printf (s, "%d", tab_array->tabs[i].location); if (tab_array->positions_in_pixels) g_string_append (s, "px"); + + if (tab_array->tabs[i].decimal_point != 0) + g_string_append_printf (s, ":%d", tab_array->tabs[i].decimal_point); } return g_string_free (s, FALSE); @@ -446,14 +454,39 @@ pango_tab_array_from_string (const char *text) { char *endp; gint64 pos; + PangoTabAlign align; + + if (g_str_has_prefix (p, "left:")) + { + align = PANGO_TAB_LEFT; + p += strlen ("left:"); + } + else if (g_str_has_prefix (p, "right:")) + { + align = PANGO_TAB_RIGHT; + p += strlen ("right:"); + } + else if (g_str_has_prefix (p, "center:")) + { + align = PANGO_TAB_CENTER; + p += strlen ("center:"); + } + else if (g_str_has_prefix (p, "decimal:")) + { + align = PANGO_TAB_DECIMAL; + p += strlen ("decimal:"); + } + else + { + align = PANGO_TAB_LEFT; + } pos = g_ascii_strtoll (p, &endp, 10); if (pos < 0 || (pixels && *endp != 'p') || - (!pixels && !g_ascii_isspace (*endp) && *endp != '\0')) goto fail; + (!pixels && !g_ascii_isspace (*endp) && *endp != ':' && *endp != '\0')) goto fail; - pango_tab_array_set_tab (array, i, PANGO_TAB_LEFT, pos); - i++; + pango_tab_array_set_tab (array, i, align, pos); p = (const char *)endp; if (pixels) @@ -461,7 +494,23 @@ pango_tab_array_from_string (const char *text) if (p[0] != 'p' || p[1] != 'x') goto fail; p += 2; } + + if (p[0] == ':') + { + gunichar ch; + + p++; + ch = g_ascii_strtoll (p, &endp, 10); + if (!g_ascii_isspace (*endp) && *endp != '\0') goto fail; + + pango_tab_array_set_decimal_point (array, i, ch); + + p = (const char *)endp; + } + p = skip_whitespace (p); + + i++; } goto success; @@ -473,3 +522,57 @@ fail: success: return array; } + +/** + * pango_tab_array_set_decimal_point: + * @tab_array: a `PangoTabArray` + * @tab_index: the index of a tab stop + * @decimal_point: the decimal point to use + * + * Sets the decimal point to use. + * + * This is only relevant for %PANGO_TAB_DECIMAL. + * + * By default, Pango uses the decimal point according + * to the current locale. + * + * Since: 1.50 + */ +void +pango_tab_array_set_decimal_point (PangoTabArray *tab_array, + int tab_index, + gunichar decimal_point) +{ + g_return_if_fail (tab_array != NULL); + g_return_if_fail (tab_index >= 0); + + if (tab_index >= tab_array->size) + pango_tab_array_resize (tab_array, tab_index + 1); + + tab_array->tabs[tab_index].decimal_point = decimal_point; +} + +/** + * pango_tab_array_get_decimal_point: + * @tab_array: a `PangoTabArray` + * @tab_index: the index of a tab stop + * + * Gets the decimal point to use. + * + * This is only relevant for %PANGO_TAB_DECIMAL. + * + * The default value of 0 means that Pango will use the + * decimal point according to the current locale. + * + * Since: 1.50 + */ +gunichar +pango_tab_array_get_decimal_point (PangoTabArray *tab_array, + int tab_index) +{ + g_return_val_if_fail (tab_array != NULL, 0); + g_return_val_if_fail (tab_index < tab_array->size, 0); + g_return_val_if_fail (tab_index >= 0, 0); + + return tab_array->tabs[tab_index].decimal_point; +} diff --git a/pango/pango-tabs.h b/pango/pango-tabs.h index d2a68d5a..0792a36a 100644 --- a/pango/pango-tabs.h +++ b/pango/pango-tabs.h @@ -30,21 +30,27 @@ typedef struct _PangoTabArray PangoTabArray; /** * PangoTabAlign: - * @PANGO_TAB_LEFT: the tab stop appears to the left of the text. + * @PANGO_TAB_LEFT: the text appears to the right of the tab stop position + * @PANGO_TAB_RIGHT: the text appears to the left of the tab stop position + * until the available space is filled + * @PANGO_TAB_CENTER: the text is centered at the tab stop position + * until the available space is filled + * @PANGO_TAB_DECIMAL: text before the first '.' appears to the left of the + * tab stop position (until the available space is filled), the rest to + * the right * - * `PangoTabAlign` specifies where a tab stop appears relative to the text. + * `PangoTabAlign` specifies where the text appears relative to the tab stop + * position. + * + * Support for tab alignments other than %PANGO_TAB_LEFT was added + * in Pango 1.50. */ typedef enum { - PANGO_TAB_LEFT - - /* These are not supported now, but may be in the - * future. - * - * PANGO_TAB_RIGHT, - * PANGO_TAB_CENTER, - * PANGO_TAB_NUMERIC - */ + PANGO_TAB_LEFT, + PANGO_TAB_RIGHT, + PANGO_TAB_CENTER, + PANGO_TAB_DECIMAL } PangoTabAlign; #define PANGO_TYPE_TAB_ARRAY (pango_tab_array_get_type ()) @@ -92,6 +98,13 @@ char * pango_tab_array_to_string (PangoTabArray *tab_array); PANGO_AVAILABLE_IN_1_50 PangoTabArray * pango_tab_array_from_string (const char *text); +PANGO_AVAILABLE_IN_1_50 +void pango_tab_array_set_decimal_point (PangoTabArray *tab_array, + int tab_index, + gunichar decimal_point); +PANGO_AVAILABLE_IN_1_50 +gunichar pango_tab_array_get_decimal_point (PangoTabArray *tab_array, + int tab_index); G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoTabArray, pango_tab_array_free) diff --git a/pango/serializer.c b/pango/serializer.c index 6e394a1c..fe0fc25c 100644 --- a/pango/serializer.c +++ b/pango/serializer.c @@ -218,9 +218,17 @@ add_tab_array (JsonBuilder *builder, json_builder_begin_array (builder); for (int i = 0; i < pango_tab_array_get_size (tabs); i++) { + PangoTabAlign align; int pos; - pango_tab_array_get_tab (tabs, i, NULL, &pos); + pango_tab_array_get_tab (tabs, i, &align, &pos); + json_builder_begin_object (builder); + json_builder_set_member_name (builder, "position"); json_builder_add_int_value (builder, pos); + json_builder_set_member_name (builder, "alignment"); + add_enum_value (builder, PANGO_TYPE_TAB_ALIGN, align, FALSE); + json_builder_set_member_name (builder, "decimal-point"); + json_builder_add_int_value (builder, pango_tab_array_get_decimal_point (tabs, i)); + json_builder_end_object (builder); } json_builder_end_array (builder); @@ -1133,9 +1141,35 @@ json_to_tab_array (JsonReader *reader, for (int i = 0; i < json_reader_count_elements (reader); i++) { int pos; + PangoTabAlign align = PANGO_TAB_LEFT; + gunichar ch = 0; + json_reader_read_element (reader, i); - pos = json_reader_get_int_value (reader); - pango_tab_array_set_tab (tabs, i, PANGO_TAB_LEFT, pos); + if (json_reader_is_object (reader)) + { + json_reader_read_member (reader, "position"); + pos = json_reader_get_int_value (reader); + json_reader_end_member (reader); + json_reader_read_member (reader, "alignment"); + + align = get_enum_value (PANGO_TYPE_TAB_ALIGN, + json_reader_get_string_value (reader), + FALSE, + error); + if (align == -1) + goto fail; + json_reader_end_member (reader); + json_reader_read_member (reader, "decimal-point"); + ch = json_reader_get_int_value (reader); + json_reader_end_member (reader); + } + else + { + pos = json_reader_get_int_value (reader); + } + + pango_tab_array_set_tab (tabs, i, align, pos); + pango_tab_array_set_decimal_point (tabs, i, ch); json_reader_end_element (reader); } } |