[pango/serialization-improvements: 7/9] Optionally serialize output
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/serialization-improvements: 7/9] Optionally serialize output
- Date: Tue, 23 Nov 2021 04:19:15 +0000 (UTC)
commit b90e4bde5e86ca483419f620ef3708dd6138b187
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Nov 22 20:33:11 2021 -0500
Optionally serialize output
If requested, serialize lines, runs, and log attrs.
This will let us use the serialization format to
record not just the test inputs, but outputs as
well.
pango/pango-layout.h | 4 +-
pango/serializer.c | 286 +++++++++++++++++++++++++++++++++++++++-
tests/layouts/valid-1.expected | 43 ------
tests/layouts/valid-10.expected | 37 ------
tests/layouts/valid-11.expected | 53 --------
tests/layouts/valid-12.expected | 35 -----
tests/layouts/valid-13.expected | 35 -----
tests/layouts/valid-14.expected | 38 ------
tests/layouts/valid-15.expected | 36 -----
tests/layouts/valid-16.expected | 37 ------
tests/layouts/valid-17.expected | 35 -----
tests/layouts/valid-18.expected | 40 ------
tests/layouts/valid-19.expected | 42 ------
tests/layouts/valid-2.expected | 42 ------
tests/layouts/valid-20.expected | 40 ------
tests/layouts/valid-22.expected | 111 ----------------
tests/layouts/valid-3.expected | 33 -----
tests/layouts/valid-4.expected | 44 -------
tests/layouts/valid-5.expected | 56 --------
tests/layouts/valid-6.expected | 33 -----
tests/layouts/valid-7.expected | 43 ------
tests/layouts/valid-8.expected | 34 -----
tests/layouts/valid-9.expected | 49 -------
23 files changed, 288 insertions(+), 918 deletions(-)
---
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index 605d41d7..0e0e04be 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -355,7 +355,8 @@ GSList * pango_layout_get_lines_readonly (PangoLayout *layout);
* PangoLayoutSerializeFlags:
* @PANGO_LAYOUT_SERIALIZE_DEFAULT: Default behavior
* @PANGO_LAYOUT_SERIALIZE_CONTEXT: Include context information in
- * the serialization
+ * @PANGO_LAYOUT_SERIALIZE_OUTPUT: Include information about the
+ * formatted output in the serialization
*
* Flags that influence the behavior of [method@Pango.Layout.serialize].
*
@@ -364,6 +365,7 @@ GSList * pango_layout_get_lines_readonly (PangoLayout *layout);
typedef enum {
PANGO_LAYOUT_SERIALIZE_DEFAULT = 0,
PANGO_LAYOUT_SERIALIZE_CONTEXT = 1 << 0,
+ PANGO_LAYOUT_SERIALIZE_OUTPUT = 1 << 1,
} PangoLayoutSerializeFlags;
PANGO_AVAILABLE_IN_1_50
diff --git a/pango/serializer.c b/pango/serializer.c
index 204c88bb..1a7cdcf5 100644
--- a/pango/serializer.c
+++ b/pango/serializer.c
@@ -257,7 +257,7 @@ add_context (JsonBuilder *builder,
json_builder_set_member_name (builder, "gravity-hint");
add_enum_value (builder, PANGO_TYPE_GRAVITY_HINT, context->gravity_hint, FALSE);
- json_builder_set_member_name (builder, "direction");
+ json_builder_set_member_name (builder, "base-dir");
add_enum_value (builder, PANGO_TYPE_DIRECTION, context->base_dir, FALSE);
json_builder_set_member_name (builder, "round-glyph-positions");
@@ -280,6 +280,284 @@ add_context (JsonBuilder *builder,
json_builder_end_object (builder);
}
+static void
+add_log_attrs (JsonBuilder *builder,
+ PangoLayout *layout)
+{
+ const PangoLogAttr *log_attrs;
+ int n_attrs;
+
+ json_builder_set_member_name (builder, "log-attrs");
+ json_builder_begin_array (builder);
+
+ log_attrs = pango_layout_get_log_attrs_readonly (layout, &n_attrs);
+ for (int i = 0; i < n_attrs; i++)
+ {
+ json_builder_begin_object (builder);
+ if (log_attrs[i].is_line_break)
+ {
+ json_builder_set_member_name (builder, "line-break");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_mandatory_break)
+ {
+ json_builder_set_member_name (builder, "mandatory-break");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_char_break)
+ {
+ json_builder_set_member_name (builder, "char-break");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_white)
+ {
+ json_builder_set_member_name (builder, "white");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_cursor_position)
+ {
+ json_builder_set_member_name (builder, "cursor-position");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_word_start)
+ {
+ json_builder_set_member_name (builder, "word-start");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_word_end)
+ {
+ json_builder_set_member_name (builder, "word-end");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_sentence_boundary)
+ {
+ json_builder_set_member_name (builder, "sentence-boundary");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_sentence_start)
+ {
+ json_builder_set_member_name (builder, "sentence-start");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_sentence_end)
+ {
+ json_builder_set_member_name (builder, "sentence-end");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].backspace_deletes_character)
+ {
+ json_builder_set_member_name (builder, "backspace-deletes-character");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_expandable_space)
+ {
+ json_builder_set_member_name (builder, "expandable-space");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].is_word_boundary)
+ {
+ json_builder_set_member_name (builder, "word-boundary");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].break_inserts_hyphen)
+ {
+ json_builder_set_member_name (builder, "break-inserts-hyphen");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ if (log_attrs[i].break_removes_preceding)
+ {
+ json_builder_set_member_name (builder, "break-removes_preceding");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+ json_builder_end_object (builder);
+ }
+
+ json_builder_end_array (builder);
+}
+
+#define ANALYSIS_FLAGS (PANGO_ANALYSIS_FLAG_CENTERED_BASELINE | \
+ PANGO_ANALYSIS_FLAG_IS_ELLIPSIS | \
+ PANGO_ANALYSIS_FLAG_NEED_HYPHEN)
+
+static void
+add_run (JsonBuilder *builder,
+ PangoLayout *layout,
+ PangoLayoutRun *run)
+{
+ PangoFontDescription *desc;
+ char *str;
+
+ json_builder_begin_object (builder);
+
+ json_builder_set_member_name (builder, "offset");
+ json_builder_add_int_value (builder, run->item->offset);
+
+ json_builder_set_member_name (builder, "length");
+ json_builder_add_int_value (builder, run->item->length);
+
+ str = g_strndup (layout->text + run->item->offset, run->item->length);
+ json_builder_set_member_name (builder, "text");
+ json_builder_add_string_value (builder, str);
+ g_free (str);
+
+ json_builder_set_member_name (builder, "bidi-level");
+ json_builder_add_int_value (builder, run->item->analysis.level);
+
+ json_builder_set_member_name (builder, "gravity");
+ add_enum_value (builder, PANGO_TYPE_GRAVITY, run->item->analysis.gravity, FALSE);
+
+ json_builder_set_member_name (builder, "language");
+ json_builder_add_string_value (builder, pango_language_to_string (run->item->analysis.language));
+
+ json_builder_set_member_name (builder, "script");
+ add_enum_value (builder, PANGO_TYPE_SCRIPT, run->item->analysis.script, FALSE);
+
+ json_builder_set_member_name (builder, "font");
+ desc = pango_font_describe (run->item->analysis.font);
+ str = pango_font_description_to_string (desc);
+ json_builder_add_string_value (builder, str);
+ g_free (str);
+ pango_font_description_free (desc);
+
+ json_builder_set_member_name (builder, "flags");
+ json_builder_add_int_value (builder, run->item->analysis.flags & ANALYSIS_FLAGS);
+
+ if (run->item->analysis.extra_attrs)
+ {
+ GSList *l;
+
+ json_builder_set_member_name (builder, "extra-attributes");
+
+ json_builder_begin_array (builder);
+ for (l = run->item->analysis.extra_attrs; l; l = l->next)
+ {
+ PangoAttribute *attr = l->data;
+ add_attribute (builder, attr);
+ }
+ json_builder_end_array (builder);
+ }
+
+ json_builder_set_member_name (builder, "y-offset");
+ json_builder_add_int_value (builder, run->y_offset);
+
+ json_builder_set_member_name (builder, "start-x-offset");
+ json_builder_add_int_value (builder, run->start_x_offset);
+
+ json_builder_set_member_name (builder, "end-x-offset");
+ json_builder_add_int_value (builder, run->end_x_offset);
+
+ json_builder_set_member_name (builder, "glyphs");
+ json_builder_begin_array (builder);
+ for (int i = 0; i < run->glyphs->num_glyphs; i++)
+ {
+ json_builder_begin_object (builder);
+
+ json_builder_set_member_name (builder, "glyph");
+ json_builder_add_int_value (builder, run->glyphs->glyphs[i].glyph);
+
+ json_builder_set_member_name (builder, "width");
+ json_builder_add_int_value (builder, run->glyphs->glyphs[i].geometry.width);
+
+ if (run->glyphs->glyphs[i].geometry.x_offset != 0)
+ {
+ json_builder_set_member_name (builder, "x-offset");
+ json_builder_add_int_value (builder, run->glyphs->glyphs[i].geometry.x_offset);
+ }
+
+ if (run->glyphs->glyphs[i].geometry.y_offset != 0)
+ {
+ json_builder_set_member_name (builder, "y-offset");
+ json_builder_add_int_value (builder, run->glyphs->glyphs[i].geometry.y_offset);
+ }
+
+ if (run->glyphs->glyphs[i].attr.is_cluster_start)
+ {
+ json_builder_set_member_name (builder, "is-cluster-start");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+
+ if (run->glyphs->glyphs[i].attr.is_color)
+ {
+ json_builder_set_member_name (builder, "is-color");
+ json_builder_add_boolean_value (builder, TRUE);
+ }
+
+ json_builder_set_member_name (builder, "log-cluster");
+ json_builder_add_int_value (builder, run->glyphs->log_clusters[i]);
+
+ json_builder_end_object (builder);
+ }
+
+ json_builder_end_array (builder);
+
+ json_builder_end_object (builder);
+}
+
+#undef ANALYSIS_FLAGS
+
+static void
+add_line (JsonBuilder *builder,
+ PangoLayoutLine *line)
+{
+ json_builder_begin_object (builder);
+
+ json_builder_set_member_name (builder, "start-index");
+ json_builder_add_int_value (builder, line->start_index);
+
+ json_builder_set_member_name (builder, "length");
+ json_builder_add_int_value (builder, line->length);
+
+ json_builder_set_member_name (builder, "paragraph-start");
+ json_builder_add_boolean_value (builder, line->is_paragraph_start);
+
+ json_builder_set_member_name (builder, "direction");
+ add_enum_value (builder, PANGO_TYPE_DIRECTION, line->resolved_dir, FALSE);
+
+ json_builder_set_member_name (builder, "runs");
+ json_builder_begin_array (builder);
+ for (GSList *l = line->runs; l; l = l->next)
+ {
+ PangoLayoutRun *run = l->data;
+ add_run (builder, line->layout, run);
+ }
+ json_builder_end_array (builder);
+
+ json_builder_end_object (builder);
+}
+
+static void
+add_output (JsonBuilder *builder,
+ PangoLayout *layout)
+{
+ int width, height;
+
+ json_builder_begin_object (builder);
+
+ json_builder_set_member_name (builder, "is-wrapped");
+ json_builder_add_boolean_value (builder, pango_layout_is_wrapped (layout));
+
+ json_builder_set_member_name (builder, "is-ellipsized");
+ json_builder_add_boolean_value (builder, pango_layout_is_ellipsized (layout));
+
+ pango_layout_get_size (layout, &width, &height);
+ json_builder_set_member_name (builder, "width");
+ json_builder_add_int_value (builder, width);
+ json_builder_set_member_name (builder, "height");
+ json_builder_add_int_value (builder, height);
+
+ add_log_attrs (builder, layout);
+ json_builder_set_member_name (builder, "lines");
+ json_builder_begin_array (builder);
+ for (GSList *l = layout->lines; l; l = l->next)
+ {
+ PangoLayoutLine *line = l->data;
+ add_line (builder, line);
+ }
+ json_builder_end_array (builder);
+
+ json_builder_end_object (builder);
+}
+
static JsonNode *
layout_to_json (PangoLayout *layout,
PangoLayoutSerializeFlags flags)
@@ -384,6 +662,12 @@ layout_to_json (PangoLayout *layout,
json_builder_add_double_value (builder, layout->line_spacing);
}
+ if (flags & PANGO_LAYOUT_SERIALIZE_OUTPUT)
+ {
+ json_builder_set_member_name (builder, "output");
+ add_output (builder, layout);
+ }
+
json_builder_end_object (builder);
root = json_builder_get_root (builder);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]