summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-11-25 15:33:47 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-11-25 15:33:47 +0000
commitf37d293b9cfcc43def6fe4be0483b898774e5a2f (patch)
treee920196bc79edae865d1365fb89f894385fa86df
parent55efd092b0319f2a2697c510eafc2b0b23597d26 (diff)
parent553eac2ba028a87718ca20180cabe78fa3bc0204 (diff)
downloadpango-f37d293b9cfcc43def6fe4be0483b898774e5a2f.tar.gz
Merge branch 'serialization-improvements' into 'main'
Rename the serialize errors See merge request GNOME/pango!520
-rw-r--r--pango/fonts.c17
-rw-r--r--pango/pango-font-private.h5
-rw-r--r--pango/pango-font.h3
-rw-r--r--pango/pango-layout.h78
-rw-r--r--pango/pangofc-font.c22
-rw-r--r--pango/serializer.c899
-rw-r--r--pango/shape.c8
-rw-r--r--tests/fonts/Cantarell-VF.otfbin0 -> 170588 bytes
-rw-r--r--tests/fonts/DejaVuSans.ttfbin0 -> 757076 bytes
-rw-r--r--tests/fonts/README4
-rw-r--r--tests/fonts/emoji-subset.ttfbin0 -> 35236 bytes
-rw-r--r--tests/layouts/bratwurst.expected32
-rw-r--r--tests/layouts/bratwurst.layout226
-rw-r--r--tests/layouts/bratwurst2.layout188
-rw-r--r--tests/layouts/bratwurst3.layout318
-rw-r--r--tests/layouts/bratwurst4.layout245
-rw-r--r--tests/layouts/effigy.layout188
-rw-r--r--tests/layouts/kebab.layout254
-rw-r--r--tests/layouts/valid-1.expected43
-rw-r--r--tests/layouts/valid-1.layout673
-rw-r--r--tests/layouts/valid-10.expected37
-rw-r--r--tests/layouts/valid-10.layout413
-rw-r--r--tests/layouts/valid-11.expected53
-rw-r--r--tests/layouts/valid-11.layout442
-rw-r--r--tests/layouts/valid-12.expected35
-rw-r--r--tests/layouts/valid-12.layout775
-rw-r--r--tests/layouts/valid-13.expected35
-rw-r--r--tests/layouts/valid-13.layout786
-rw-r--r--tests/layouts/valid-14.expected38
-rw-r--r--tests/layouts/valid-14.layout524
-rw-r--r--tests/layouts/valid-15.expected36
-rw-r--r--tests/layouts/valid-15.layout1029
-rw-r--r--tests/layouts/valid-16.expected37
-rw-r--r--tests/layouts/valid-16.layout1036
-rw-r--r--tests/layouts/valid-17.expected35
-rw-r--r--tests/layouts/valid-17.layout332
-rw-r--r--tests/layouts/valid-18.expected40
-rw-r--r--tests/layouts/valid-18.layout754
-rw-r--r--tests/layouts/valid-19.expected42
-rw-r--r--tests/layouts/valid-19.layout618
-rw-r--r--tests/layouts/valid-2.expected42
-rw-r--r--tests/layouts/valid-2.layout601
-rw-r--r--tests/layouts/valid-20.expected40
-rw-r--r--tests/layouts/valid-20.layout218
-rw-r--r--tests/layouts/valid-22.expected111
-rw-r--r--tests/layouts/valid-22.layout639
-rw-r--r--tests/layouts/valid-3.expected33
-rw-r--r--tests/layouts/valid-3.layout220
-rw-r--r--tests/layouts/valid-4.expected44
-rw-r--r--tests/layouts/valid-4.layout1958
-rw-r--r--tests/layouts/valid-5.expected56
-rw-r--r--tests/layouts/valid-5.layout1777
-rw-r--r--tests/layouts/valid-6.expected33
-rw-r--r--tests/layouts/valid-6.layout408
-rw-r--r--tests/layouts/valid-7.expected43
-rw-r--r--tests/layouts/valid-7.layout625
-rw-r--r--tests/layouts/valid-8.expected34
-rw-r--r--tests/layouts/valid-8.layout412
-rw-r--r--tests/layouts/valid-9.expected49
-rw-r--r--tests/layouts/valid-9.layout515
-rw-r--r--tests/meson.build14
-rw-r--r--tests/test-common.c64
-rw-r--r--tests/test-common.h4
-rw-r--r--tests/test-layout.c392
-rw-r--r--tests/testserialize.c82
-rw-r--r--utils/viewer-render.c2
66 files changed, 17285 insertions, 1431 deletions
diff --git a/pango/fonts.c b/pango/fonts.c
index 9d3c1bf3..d94feaf8 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -1752,6 +1752,13 @@ pango_font_default_get_face (PangoFont *font)
}
static void
+pango_font_default_get_matrix (PangoFont *font,
+ PangoMatrix *matrix)
+{
+ *matrix = (PangoMatrix) PANGO_MATRIX_INIT;
+}
+
+static void
pango_font_class_init (PangoFontClass *class G_GNUC_UNUSED)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
@@ -1766,6 +1773,7 @@ pango_font_class_init (PangoFontClass *class G_GNUC_UNUSED)
pclass->get_scale_factors = pango_font_default_get_scale_factors;
pclass->has_char = pango_font_default_has_char;
pclass->get_face = pango_font_default_get_face;
+ pclass->get_matrix = pango_font_default_get_matrix;
}
static void
@@ -2717,6 +2725,15 @@ pango_font_get_languages (PangoFont *font)
return pclass->get_languages (font);
}
+void
+pango_font_get_matrix (PangoFont *font,
+ PangoMatrix *matrix)
+{
+ PangoFontClassPrivate *pclass = PANGO_FONT_GET_CLASS_PRIVATE (font);
+
+ pclass->get_matrix (font, matrix);
+}
+
gboolean
pango_font_is_hinted (PangoFont *font)
{
diff --git a/pango/pango-font-private.h b/pango/pango-font-private.h
index 93ce27aa..1e38371d 100644
--- a/pango/pango-font-private.h
+++ b/pango/pango-font-private.h
@@ -45,12 +45,17 @@ typedef struct {
gboolean (* has_char) (PangoFont *font,
gunichar wc);
PangoFontFace * (* get_face) (PangoFont *font);
+ void (* get_matrix) (PangoFont *font,
+ PangoMatrix *matrix);
} PangoFontClassPrivate;
gboolean pango_font_is_hinted (PangoFont *font);
void pango_font_get_scale_factors (PangoFont *font,
double *x_scale,
double *y_scale);
+void pango_font_get_matrix (PangoFont *font,
+ PangoMatrix *matrix);
+
G_END_DECLS
diff --git a/pango/pango-font.h b/pango/pango-font.h
index c56fb792..bfe4bc31 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -634,6 +634,9 @@ hb_font_t * pango_font_get_hb_font (PangoFont *font);
PANGO_AVAILABLE_IN_1_50
PangoLanguage ** pango_font_get_languages (PangoFont *font);
+PANGO_AVAILABLE_IN_1_50
+GBytes * pango_font_serialize (PangoFont *font);
+
/**
* PANGO_GLYPH_EMPTY:
*
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index 3b725adc..32dc16f0 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -351,30 +351,78 @@ GSList * pango_layout_get_lines (PangoLayout *layout);
PANGO_AVAILABLE_IN_1_16
GSList * pango_layout_get_lines_readonly (PangoLayout *layout);
-#define PANGO_LAYOUT_SERIALIZE_ERROR (pango_layout_serialize_error_quark ())
-
+/**
+ * PangoLayoutSerializeFlags:
+ * @PANGO_LAYOUT_SERIALIZE_DEFAULT: Default behavior
+ * @PANGO_LAYOUT_SERIALIZE_CONTEXT: Include context information
+ * @PANGO_LAYOUT_SERIALIZE_OUTPUT: Include information about the formatted output
+ *
+ * Flags that influence the behavior of [method@Pango.Layout.serialize].
+ *
+ * New members may be added to this enumeration over time.
+ */
typedef enum {
- PANGO_LAYOUT_SERIALIZE_INVALID,
- PANGO_LAYOUT_SERIALIZE_INVALID_SYNTAX,
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE,
- PANGO_LAYOUT_SERIALIZE_MISSING_VALUE,
-} PangoLayoutSerializeError;
+ PANGO_LAYOUT_SERIALIZE_DEFAULT = 0,
+ PANGO_LAYOUT_SERIALIZE_CONTEXT = 1 << 0,
+ PANGO_LAYOUT_SERIALIZE_OUTPUT = 1 << 1,
+} PangoLayoutSerializeFlags;
PANGO_AVAILABLE_IN_1_50
-GQuark pango_layout_serialize_error_quark (void);
+GBytes * pango_layout_serialize (PangoLayout *layout,
+ PangoLayoutSerializeFlags flags);
PANGO_AVAILABLE_IN_1_50
-GBytes * pango_layout_serialize (PangoLayout *layout);
+gboolean pango_layout_write_to_file (PangoLayout *layout,
+ PangoLayoutSerializeFlags flags,
+
+ const char *filename,
+ GError **error);
+
+#define PANGO_LAYOUT_DESERIALIZE_ERROR (pango_layout_deserialize_error_quark ())
+
+/**
+ * PangoLayoutDeserializeError:
+ * @PANGO_LAYOUT_SERIALIZE_INVALID: Unspecified error
+ * @PANGO_LAYOUT_SERIALIZE_INVALID_SYNTAX: The serialized data had
+ * the wrong structure (e.g. a member was expected to be a JSon object,
+ * but was an array)
+ * @PANGO_LAYOUT_SERIALIZE_INVALID_VALUE: A JSon value could not be
+ * interpreted
+ * @PANGO_LAYOUT_SERIALIZE_MISSING_VALUE: A required JSon member was
+ * not found
+ *
+ * Errors that can be returned by [func@Pango.Layout.deserialize].
+ */
+typedef enum {
+ PANGO_LAYOUT_DESERIALIZE_INVALID,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_SYNTAX,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_VALUE,
+ PANGO_LAYOUT_DESERIALIZE_MISSING_VALUE,
+} PangoLayoutDeserializeError;
PANGO_AVAILABLE_IN_1_50
-PangoLayout * pango_layout_deserialize (PangoContext *context,
- GBytes *bytes,
- GError **error);
+GQuark pango_layout_deserialize_error_quark (void);
+
+/**
+ * PangoLayoutDeserializeFlags:
+ * @PANGO_LAYOUT_DESERIALIZE_DEFAULT: Default behavior
+ * @PANGO_LAYOUT_DESERIALIZE_CONTEXT: Apply context information
+ * from the serialization to the `PangoContext`
+ *
+ * Flags that influence the behavior of [method@Pango.Layout.deserialize].
+ *
+ * New members may be added to this enumeration over time.
+ */
+typedef enum {
+ PANGO_LAYOUT_DESERIALIZE_DEFAULT = 0,
+ PANGO_LAYOUT_DESERIALIZE_CONTEXT = 1 << 0,
+} PangoLayoutDeserializeFlags;
PANGO_AVAILABLE_IN_1_50
-gboolean pango_layout_write_to_file (PangoLayout *layout,
- const char *filename,
- GError **error);
+PangoLayout * pango_layout_deserialize (PangoContext *context,
+ GBytes *bytes,
+ PangoLayoutDeserializeFlags flags,
+ GError **error);
#define PANGO_TYPE_LAYOUT_LINE (pango_layout_line_get_type ())
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 74503b91..5635e0be 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -75,6 +75,8 @@ static gboolean _pango_fc_font_is_hinted (PangoFont *fon
static void _pango_fc_font_get_scale_factors (PangoFont *font,
double *x_scale,
double *y_scale);
+static void pango_fc_font_get_matrix (PangoFont *font,
+ PangoMatrix *matrix);
#define PANGO_FC_FONT_LOCK_FACE(font) (PANGO_FC_FONT_GET_CLASS (font)->lock_face (font))
#define PANGO_FC_FONT_UNLOCK_FACE(font) (PANGO_FC_FONT_GET_CLASS (font)->unlock_face (font))
@@ -109,6 +111,7 @@ pango_fc_font_class_init (PangoFcFontClass *class)
pclass->get_languages = _pango_fc_font_get_languages;
pclass->is_hinted = _pango_fc_font_is_hinted;
pclass->get_scale_factors = _pango_fc_font_get_scale_factors;
+ pclass->get_matrix = pango_fc_font_get_matrix;
/**
* PangoFcFont:pattern:
@@ -1110,3 +1113,22 @@ _pango_fc_font_get_scale_factors (PangoFont *font,
pango_matrix_get_font_scale_factors (&fcfont->matrix, x_scale, y_scale);
}
+
+static void
+pango_fc_font_get_matrix (PangoFont *font,
+ PangoMatrix *matrix)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (font);
+ FcMatrix fc_matrix, *fc_matrix_val;
+
+ FcMatrixInit (&fc_matrix);
+ for (int i = 0; FcPatternGetMatrix (fcfont->font_pattern, FC_MATRIX, i, &fc_matrix_val) == FcResultMatch; i++)
+ FcMatrixMultiply (&fc_matrix, &fc_matrix, fc_matrix_val);
+
+ matrix->xx = fc_matrix.xx;
+ matrix->xy = - fc_matrix.xy;
+ matrix->yx = - fc_matrix.yx;
+ matrix->yy = fc_matrix.yy;
+ matrix->x0 = 0.;
+ matrix->y0 = 0.;
+}
diff --git a/pango/serializer.c b/pango/serializer.c
index 576e6cf6..6e394a1c 100644
--- a/pango/serializer.c
+++ b/pango/serializer.c
@@ -23,13 +23,16 @@
#include <pango/pango-layout.h>
#include <pango/pango-layout-private.h>
+#include <pango/pango-context-private.h>
#include <pango/pango-enum-types.h>
+#include <pango/pango-font-private.h>
+#include <hb-ot.h>
#include <json-glib/json-glib.h>
/* {{{ Error handling */
-G_DEFINE_QUARK(pango-layout-serialize-error-quark, pango_layout_serialize_error)
+G_DEFINE_QUARK(pango-layout-deserialize-error-quark, pango_layout_deserialize_error)
/* }}} */
/* {{{ Serialization */
@@ -177,9 +180,17 @@ add_attr_list (JsonBuilder *builder,
{
GSList *attributes, *l;
- json_builder_begin_array (builder);
+ if (!attrs)
+ return;
attributes = pango_attr_list_get_attributes (attrs);
+
+ if (!attributes)
+ return;
+
+ json_builder_set_member_name (builder, "attributes");
+ json_builder_begin_array (builder);
+
for (l = attributes; l; l = l->next)
{
PangoAttribute *attr = l->data;
@@ -194,6 +205,11 @@ static void
add_tab_array (JsonBuilder *builder,
PangoTabArray *tabs)
{
+ if (!tabs || pango_tab_array_get_size (tabs) == 0)
+ return;
+
+ json_builder_set_member_name (builder, "tabs");
+
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "positions-in-pixels");
@@ -211,25 +227,479 @@ add_tab_array (JsonBuilder *builder,
json_builder_end_object (builder);
}
+static void
+add_context (JsonBuilder *builder,
+ PangoContext *context)
+{
+ char *str;
+ const PangoMatrix *matrix;
+ PangoMatrix identity = PANGO_MATRIX_INIT;
+
+ json_builder_begin_object (builder);
+
+ /* Note: since we don't create the context when deserializing,
+ * we don't strip out default values here to ensure that the
+ * context gets updated as expected.
+ */
+
+ str = pango_font_description_to_string (context->font_desc);
+ json_builder_set_member_name (builder, "font");
+ json_builder_add_string_value (builder, str);
+ g_free (str);
+
+ if (context->set_language)
+ {
+ json_builder_set_member_name (builder, "language");
+ json_builder_add_string_value (builder, pango_language_to_string (context->set_language));
+ }
+
+ json_builder_set_member_name (builder, "base-gravity");
+ add_enum_value (builder, PANGO_TYPE_GRAVITY, context->base_gravity, FALSE);
+
+ 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, "base-dir");
+ add_enum_value (builder, PANGO_TYPE_DIRECTION, context->base_dir, FALSE);
+
+ json_builder_set_member_name (builder, "round-glyph-positions");
+ json_builder_add_boolean_value (builder, context->round_glyph_positions);
+
+ json_builder_set_member_name (builder, "transform");
+ matrix = pango_context_get_matrix (context);
+ if (!matrix)
+ matrix = &identity;
+
+ json_builder_begin_array (builder);
+ json_builder_add_double_value (builder, matrix->xx);
+ json_builder_add_double_value (builder, matrix->xy);
+ json_builder_add_double_value (builder, matrix->yx);
+ json_builder_add_double_value (builder, matrix->yy);
+ json_builder_add_double_value (builder, matrix->x0);
+ json_builder_add_double_value (builder, matrix->y0);
+ json_builder_end_array (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);
+}
+
+static void
+add_font (JsonBuilder *builder,
+ PangoFont *font)
+{
+ PangoFontDescription *desc;
+ char *str;
+ hb_font_t *hb_font;
+ hb_face_t *face;
+ hb_blob_t *blob;
+ const char *data;
+ guint length;
+ const int *coords;
+ hb_feature_t features[32];
+ PangoMatrix matrix;
+
+ json_builder_begin_object (builder);
+
+ json_builder_set_member_name (builder, "description");
+
+ desc = pango_font_describe (font);
+ str = pango_font_description_to_string (desc);
+ json_builder_add_string_value (builder, str);
+ g_free (str);
+ pango_font_description_free (desc);
+
+ hb_font = pango_font_get_hb_font (font);
+ face = hb_font_get_face (hb_font);
+ blob = hb_face_reference_blob (face);
+
+ data = hb_blob_get_data (blob, &length);
+ str = g_compute_checksum_for_data (G_CHECKSUM_SHA256, (const guchar *)data, length);
+
+ json_builder_set_member_name (builder, "checksum");
+ json_builder_add_string_value (builder, str);
+
+ g_free (str);
+ hb_blob_destroy (blob);
+
+ coords = hb_font_get_var_coords_normalized (hb_font, &length);
+ if (length > 0)
+ {
+ guint count;
+ hb_ot_var_axis_info_t *axes;
+
+ count = hb_ot_var_get_axis_count (face);
+ g_assert (count == length);
+
+ axes = g_alloca (count * sizeof (hb_ot_var_axis_info_t));
+ hb_ot_var_get_axis_infos (face, 0, &count, axes);
+
+ json_builder_set_member_name (builder, "variations");
+ json_builder_begin_object (builder);
+
+ for (int i = 0; i < length; i++)
+ {
+ char buf[5] = { 0, };
+
+ hb_tag_to_string (axes[i].tag, buf);
+ json_builder_set_member_name (builder, buf);
+ json_builder_add_int_value (builder, coords[i]);
+ }
+
+ json_builder_end_object (builder);
+ }
+
+ length = 0;
+ pango_font_get_features (font, features, G_N_ELEMENTS (features), &length);
+ if (length > 0)
+ {
+ json_builder_set_member_name (builder, "features");
+ json_builder_begin_object (builder);
+
+ for (int i = 0; i < length; i++)
+ {
+ char buf[5] = { 0, };
+
+ hb_tag_to_string (features[i].tag, buf);
+ json_builder_set_member_name (builder, buf);
+ json_builder_add_int_value (builder, features[i].value);
+ }
+
+ json_builder_end_object (builder);
+ }
+
+ pango_font_get_matrix (font, &matrix);
+ if (memcmp (&matrix, &(PangoMatrix)PANGO_MATRIX_INIT, sizeof (PangoMatrix)) != 0)
+ {
+ json_builder_set_member_name (builder, "matrix");
+ json_builder_begin_array (builder);
+ json_builder_add_double_value (builder, matrix.xx);
+ json_builder_add_double_value (builder, matrix.xy);
+ json_builder_add_double_value (builder, matrix.yx);
+ json_builder_add_double_value (builder, matrix.yy);
+ json_builder_add_double_value (builder, matrix.x0);
+ json_builder_add_double_value (builder, matrix.y0);
+ json_builder_end_array (builder);
+ }
+
+ json_builder_end_object (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)
+{
+ json_builder_begin_object (builder);
+ char *str;
+
+ 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");
+ add_font (builder, run->item->analysis.font);
+
+ 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));
+
+ json_builder_set_member_name (builder, "unknown-glyphs");
+ json_builder_add_int_value (builder, pango_layout_get_unknown_glyphs_count (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)
+layout_to_json (PangoLayout *layout,
+ PangoLayoutSerializeFlags flags)
{
JsonBuilder *builder;
JsonNode *root;
+ const char *str;
builder = json_builder_new_immutable ();
json_builder_begin_object (builder);
- json_builder_set_member_name (builder, "text");
- json_builder_add_string_value (builder, layout->text);
+ if (flags & PANGO_LAYOUT_SERIALIZE_CONTEXT)
+ {
+ json_builder_set_member_name (builder, "context");
+ add_context (builder, layout->context);
+ }
- if (layout->attrs)
+ str = (const char *) g_object_get_data (G_OBJECT (layout), "comment");
+ if (str)
{
- json_builder_set_member_name (builder, "attributes");
- add_attr_list (builder, layout->attrs);
+ json_builder_set_member_name (builder, "comment");
+ if (strstr (str, "\n") != NULL)
+ {
+ char **strs = g_strsplit (str, "\n", -1);
+
+ json_builder_begin_array (builder);
+ for (int i = 0; strs[i]; i++)
+ json_builder_add_string_value (builder, strs[i]);
+ json_builder_end_array (builder);
+
+ g_strfreev (strs);
+ }
+ else
+ json_builder_add_string_value (builder, str);
}
+ json_builder_set_member_name (builder, "text");
+ json_builder_add_string_value (builder, layout->text);
+
+ add_attr_list (builder, layout->attrs);
+
if (layout->font_desc)
{
char *str = pango_font_description_to_string (layout->font_desc);
@@ -238,11 +708,7 @@ layout_to_json (PangoLayout *layout)
g_free (str);
}
- if (layout->tabs)
- {
- json_builder_set_member_name (builder, "tabs");
- add_tab_array (builder, layout->tabs);
- }
+ add_tab_array (builder, layout->tabs);
if (layout->justify)
{
@@ -316,6 +782,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);
@@ -324,13 +796,28 @@ layout_to_json (PangoLayout *layout)
return root;
}
+static JsonNode *
+font_to_json (PangoFont *font)
+{
+ JsonBuilder *builder;
+ JsonNode *root;
+
+ builder = json_builder_new_immutable ();
+ add_font (builder, font);
+ root = json_builder_get_root (builder);
+ g_object_unref (builder);
+
+ return root;
+}
+
/* }}} */
/* {{{ Deserialization */
static int
-get_enum_value (GType type,
- const char *str,
- gboolean allow_extra)
+get_enum_value (GType type,
+ const char *str,
+ gboolean allow_extra,
+ GError **error)
{
GEnumClass *enum_class;
GEnumValue *enum_value;
@@ -351,6 +838,13 @@ get_enum_value (GType type,
return value;
}
+ g_set_error (error,
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_VALUE,
+ "Could not parse enum value of type %s: %s",
+ g_type_name (type),
+ str);
+
return -1;
}
@@ -364,11 +858,13 @@ json_to_attribute (JsonReader *reader,
guint end = PANGO_ATTR_INDEX_TO_TEXT_END;
PangoFontDescription *desc;
PangoColor color;
+ int value;
if (!json_reader_is_object (reader))
{
g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR, PANGO_LAYOUT_SERIALIZE_INVALID_SYNTAX,
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_SYNTAX,
"Attribute must be a Json object");
return NULL;
}
@@ -383,32 +879,26 @@ json_to_attribute (JsonReader *reader,
if (json_reader_read_member (reader, "type"))
{
- type = get_enum_value (PANGO_TYPE_ATTR_TYPE, json_reader_get_string_value (reader), FALSE);
- if (type == -1 || type == PANGO_ATTR_INVALID)
- {
- g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR, PANGO_LAYOUT_SERIALIZE_INVALID_VALUE,
- "Attribute \"type\" invalid: %s",
- json_reader_get_string_value (reader));
- return NULL;
- }
- json_reader_end_member (reader);
+ type = get_enum_value (PANGO_TYPE_ATTR_TYPE, json_reader_get_string_value (reader), FALSE, error);
+ if (type == -1)
+ return NULL;
}
else
{
g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR, PANGO_LAYOUT_SERIALIZE_MISSING_VALUE,
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_MISSING_VALUE,
"Attribute \"type\" missing");
- json_reader_end_member (reader);
return NULL;
}
+ json_reader_end_member (reader);
if (!json_reader_read_member (reader, "value"))
{
g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR, PANGO_LAYOUT_SERIALIZE_MISSING_VALUE,
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_MISSING_VALUE,
"Attribute \"value\" missing");
- json_reader_end_member (reader);
return NULL;
}
@@ -425,16 +915,27 @@ json_to_attribute (JsonReader *reader,
attr = pango_attr_family_new (json_reader_get_string_value (reader));
break;
case PANGO_ATTR_STYLE:
- attr = pango_attr_style_new (get_enum_value (PANGO_TYPE_STYLE, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_STYLE, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_style_new ((PangoStyle)value);
break;
case PANGO_ATTR_WEIGHT:
- attr = pango_attr_weight_new (get_enum_value (PANGO_TYPE_WEIGHT, json_reader_get_string_value (reader), TRUE));
+ value = get_enum_value (PANGO_TYPE_WEIGHT, json_reader_get_string_value (reader), TRUE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_weight_new (value);
break;
case PANGO_ATTR_VARIANT:
- attr = pango_attr_variant_new (get_enum_value (PANGO_TYPE_VARIANT, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_VARIANT, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_variant_new ((PangoVariant)value);
break;
case PANGO_ATTR_STRETCH:
- attr = pango_attr_stretch_new (get_enum_value (PANGO_TYPE_STRETCH, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_STRETCH, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ attr = pango_attr_stretch_new ((PangoStretch)value);
break;
case PANGO_ATTR_SIZE:
attr = pango_attr_size_new (json_reader_get_int_value (reader));
@@ -453,7 +954,10 @@ json_to_attribute (JsonReader *reader,
attr = pango_attr_background_new (color.red, color.green, color.blue);
break;
case PANGO_ATTR_UNDERLINE:
- attr = pango_attr_underline_new (get_enum_value (PANGO_TYPE_UNDERLINE, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_UNDERLINE, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_underline_new ((PangoUnderline)value);
break;
case PANGO_ATTR_STRIKETHROUGH:
attr = pango_attr_strikethrough_new (json_reader_get_boolean_value (reader));
@@ -486,10 +990,16 @@ json_to_attribute (JsonReader *reader,
attr = pango_attr_size_new_absolute (json_reader_get_int_value (reader));
break;
case PANGO_ATTR_GRAVITY:
- attr = pango_attr_gravity_new (get_enum_value (PANGO_TYPE_GRAVITY, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_GRAVITY, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_gravity_new ((PangoGravity)value);
break;
case PANGO_ATTR_GRAVITY_HINT:
- attr = pango_attr_gravity_hint_new (get_enum_value (PANGO_TYPE_GRAVITY_HINT, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_GRAVITY_HINT, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_gravity_hint_new ((PangoGravityHint)value);
break;
case PANGO_ATTR_FONT_FEATURES:
attr = pango_attr_font_features_new (json_reader_get_string_value (reader));
@@ -510,7 +1020,10 @@ json_to_attribute (JsonReader *reader,
attr = pango_attr_insert_hyphens_new (json_reader_get_boolean_value (reader));
break;
case PANGO_ATTR_OVERLINE:
- attr = pango_attr_overline_new (get_enum_value (PANGO_TYPE_OVERLINE, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_OVERLINE, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_overline_new ((PangoOverline)value);
break;
case PANGO_ATTR_OVERLINE_COLOR:
pango_color_parse (&color, json_reader_get_string_value (reader));
@@ -523,7 +1036,10 @@ json_to_attribute (JsonReader *reader,
attr = pango_attr_line_height_new_absolute (json_reader_get_int_value (reader));
break;
case PANGO_ATTR_TEXT_TRANSFORM:
- attr = pango_attr_text_transform_new (get_enum_value (PANGO_TYPE_TEXT_TRANSFORM, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_TEXT_TRANSFORM, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_text_transform_new ((PangoTextTransform)value);
break;
case PANGO_ATTR_WORD:
attr = pango_attr_word_new ();
@@ -532,10 +1048,16 @@ json_to_attribute (JsonReader *reader,
attr = pango_attr_sentence_new ();
break;
case PANGO_ATTR_BASELINE_SHIFT:
- attr = pango_attr_baseline_shift_new (get_enum_value (PANGO_TYPE_BASELINE_SHIFT, json_reader_get_string_value (reader), TRUE));
+ value = get_enum_value (PANGO_TYPE_BASELINE_SHIFT, json_reader_get_string_value (reader), TRUE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_baseline_shift_new (value);
break;
case PANGO_ATTR_FONT_SCALE:
- attr = pango_attr_font_scale_new (get_enum_value (PANGO_TYPE_BASELINE_SHIFT, json_reader_get_string_value (reader), FALSE));
+ value = get_enum_value (PANGO_TYPE_FONT_SCALE, json_reader_get_string_value (reader), FALSE, error);
+ if (value == -1)
+ return NULL;
+ attr = pango_attr_font_scale_new ((PangoFontScale)value);
break;
}
@@ -553,16 +1075,17 @@ json_to_attr_list (JsonReader *reader,
{
PangoAttrList *attributes;
+ attributes = pango_attr_list_new ();
+
if (!json_reader_is_array (reader))
{
g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR, PANGO_LAYOUT_SERIALIZE_INVALID_SYNTAX,
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_SYNTAX,
"\"attributes\" must be a Json array");
goto fail;
}
- attributes = pango_attr_list_new ();
-
for (int i = 0; i < json_reader_count_elements (reader); i++)
{
PangoAttribute *attr;
@@ -600,8 +1123,8 @@ json_to_tab_array (JsonReader *reader,
if (!json_reader_is_array (reader))
{
g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR,
- PANGO_LAYOUT_SERIALIZE_INVALID_SYNTAX,
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_SYNTAX,
"Tab \"positions\" must be a Json array");
goto fail;
}
@@ -626,26 +1149,165 @@ fail:
return NULL;
}
+static gboolean
+apply_json_to_context (JsonReader *reader,
+ PangoContext *context,
+ GError **error)
+{
+ if (json_reader_read_member (reader, "language"))
+ {
+ const char *value;
+ PangoLanguage *language;
+
+ value = json_reader_get_string_value (reader);
+ language = pango_language_from_string (value);
+ pango_context_set_language (context, language);
+ }
+ json_reader_end_member (reader);
+
+ if (json_reader_read_member (reader, "font"))
+ {
+ PangoFontDescription *desc;
+
+ desc = pango_font_description_from_string (json_reader_get_string_value (reader));
+ pango_context_set_font_description (context, desc);
+ pango_font_description_free (desc);
+ }
+ json_reader_end_member (reader);
+
+ if (json_reader_read_member (reader, "base-gravity"))
+ {
+ PangoGravity gravity = get_enum_value (PANGO_TYPE_GRAVITY,
+ json_reader_get_string_value (reader),
+ FALSE,
+ error);
+ if (gravity == -1)
+ return FALSE;
+
+ pango_context_set_base_gravity (context, gravity);
+ }
+ json_reader_end_member (reader);
+
+ if (json_reader_read_member (reader, "gravity-hint"))
+ {
+ PangoGravityHint gravity_hint = get_enum_value (PANGO_TYPE_GRAVITY_HINT,
+ json_reader_get_string_value (reader),
+ FALSE,
+ error);
+ if (gravity_hint == -1)
+ return FALSE;
+
+ pango_context_set_gravity_hint (context, gravity_hint);
+ }
+ json_reader_end_member (reader);
+
+ if (json_reader_read_member (reader, "base-dir"))
+ {
+ PangoDirection direction = get_enum_value (PANGO_TYPE_DIRECTION,
+ json_reader_get_string_value (reader),
+ FALSE,
+ error);
+ if (direction == -1)
+ return FALSE;
+
+ pango_context_set_base_dir (context, direction);
+ }
+ json_reader_end_member (reader);
+
+ if (json_reader_read_member (reader, "round-glyph-positions"))
+ {
+ pango_context_set_round_glyph_positions (context, json_reader_get_boolean_value (reader));
+ }
+ json_reader_end_member (reader);
+
+ if (json_reader_read_member (reader, "transform"))
+ {
+ PangoMatrix m;
+
+ json_reader_read_element (reader, 0);
+ m.xx = json_reader_get_double_value (reader);
+ json_reader_end_element (reader);
+ json_reader_read_element (reader, 1);
+ m.xy = json_reader_get_double_value (reader);
+ json_reader_end_element (reader);
+ json_reader_read_element (reader, 2);
+ m.yx = json_reader_get_double_value (reader);
+ json_reader_end_element (reader);
+ json_reader_read_element (reader, 3);
+ m.yy = json_reader_get_double_value (reader);
+ json_reader_end_element (reader);
+ json_reader_read_element (reader, 4);
+ m.x0 = json_reader_get_double_value (reader);
+ json_reader_end_element (reader);
+ json_reader_read_element (reader, 5);
+ m.y0 = json_reader_get_double_value (reader);
+ json_reader_end_element (reader);
+
+ pango_context_set_matrix (context, &m);
+ }
+ json_reader_end_member (reader);
+
+ return TRUE;
+}
+
static PangoLayout *
-json_to_layout (PangoContext *context,
- JsonNode *node,
- GError **error)
+json_to_layout (PangoContext *context,
+ JsonNode *node,
+ PangoLayoutDeserializeFlags flags,
+ GError **error)
{
JsonReader *reader;
PangoLayout *layout;
- layout = pango_layout_new (context);
-
reader = json_reader_new (node);
if (!json_reader_is_object (reader))
{
g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR,
- PANGO_LAYOUT_SERIALIZE_INVALID_SYNTAX,
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_SYNTAX,
"Layout must be a Json object");
goto fail;
}
+ if (flags & PANGO_LAYOUT_DESERIALIZE_CONTEXT)
+ {
+ if (json_reader_read_member (reader, "context"))
+ {
+ if (!apply_json_to_context (reader, context, error))
+ goto fail;
+ }
+ json_reader_end_member (reader);
+ }
+
+ layout = pango_layout_new (context);
+
+ if (json_reader_read_member (reader, "comment"))
+ {
+ if (json_reader_is_array (reader))
+ {
+ GString *s;
+
+ s = g_string_new ("");
+ for (int i = 0; i < json_reader_count_elements (reader); i++)
+ {
+ json_reader_read_element (reader, i);
+ if (s->len > 0)
+ g_string_append_c (s, '\n');
+ g_string_append (s, json_reader_get_string_value (reader));
+ json_reader_end_element (reader);
+ }
+
+ g_object_set_data_full (G_OBJECT (layout), "comment",
+ g_string_free (s, FALSE),
+ g_free);
+ }
+ else
+ g_object_set_data_full (G_OBJECT (layout), "comment",
+ g_strdup (json_reader_get_string_value (reader)),
+ g_free);
+ }
+ json_reader_end_member (reader);
+
if (json_reader_read_member (reader, "text"))
pango_layout_set_text (layout, json_reader_get_string_value (reader), -1);
json_reader_end_member (reader);
@@ -672,9 +1334,10 @@ json_to_layout (PangoContext *context,
if (!desc)
{
g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR,
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE,
- "Could not parse \"font\" value: %s",
+ PANGO_LAYOUT_DESERIALIZE_ERROR,
+ PANGO_LAYOUT_DESERIALIZE_INVALID_VALUE,
+ "Could not parse \"%s\" value: %s",
+ "font",
json_reader_get_string_value (reader));
goto fail;
}
@@ -717,16 +1380,10 @@ json_to_layout (PangoContext *context,
{
PangoAlignment align = get_enum_value (PANGO_TYPE_ALIGNMENT,
json_reader_get_string_value (reader),
- FALSE);
+ FALSE,
+ error);
if (align == -1)
- {
- g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR,
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE,
- "Could not parse \"alignment\" value: %s",
- json_reader_get_string_value (reader));
- goto fail;
- }
+ goto fail;
pango_layout_set_alignment (layout, align);
}
@@ -737,17 +1394,11 @@ json_to_layout (PangoContext *context,
{
PangoWrapMode wrap = get_enum_value (PANGO_TYPE_WRAP_MODE,
json_reader_get_string_value (reader),
- FALSE);
+ FALSE,
+ error);
if (wrap == -1)
- {
- g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR,
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE,
- "Could not parse \"wrap\" value: %s",
- json_reader_get_string_value (reader));
- goto fail;
- }
+ goto fail;
pango_layout_set_wrap (layout, wrap);
}
@@ -758,17 +1409,11 @@ json_to_layout (PangoContext *context,
{
PangoEllipsizeMode ellipsize = get_enum_value (PANGO_TYPE_ELLIPSIZE_MODE,
json_reader_get_string_value (reader),
- FALSE);
+ FALSE,
+ error);
if (ellipsize == -1)
- {
- g_set_error (error,
- PANGO_LAYOUT_SERIALIZE_ERROR,
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE,
- "Could not parse \"ellipsize\" value: %s",
- json_reader_get_string_value (reader));
- goto fail;
- }
+ goto fail;
pango_layout_set_ellipsize (layout, ellipsize);
}
@@ -801,20 +1446,22 @@ json_to_layout (PangoContext *context,
fail:
g_object_unref (reader);
- g_object_unref (layout);
+ if (layout)
+ g_object_unref (layout);
return NULL;
}
- /* }}} */
- /* {{{ Public API */
+/* }}} */
+/* {{{ Public API */
/**
* pango_layout_serialize:
* @layout: a `PangoLayout`
+ * @flags: `PangoLayoutSerializeFlags`
*
* Serializes the @layout for later deserialization via [method@Pango.Layout.deserialize].
*
- * There are no guarantees about the format of the output accross different
+ * There are no guarantees about the format of the output across different
* versions of Pango and [method@Pango.Layout.deserialize] will reject data
* that it cannot parse.
*
@@ -826,21 +1473,28 @@ fail:
* Since: 1.50
*/
GBytes *
-pango_layout_serialize (PangoLayout *layout)
+pango_layout_serialize (PangoLayout *layout,
+ PangoLayoutSerializeFlags flags)
{
JsonGenerator *generator;
JsonNode *node;
+ GString *str;
char *data;
gsize size;
- node = layout_to_json (layout);
+ g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
+
+ node = layout_to_json (layout, flags);
generator = json_generator_new ();
json_generator_set_pretty (generator, TRUE);
json_generator_set_indent (generator, 2);
json_generator_set_root (generator, node);
- data = json_generator_to_data (generator, &size);
+ str = g_string_new ("");
+ g_string_append_c (json_generator_to_gstring (generator, str), '\n');
+ size = str->len;
+ data = g_string_free (str, FALSE);
json_node_free (node);
g_object_unref (generator);
@@ -851,6 +1505,7 @@ pango_layout_serialize (PangoLayout *layout)
/**
* pango_layout_write_to_file:
* @layout: a `PangoLayout`
+ * @flags: `PangoLayoutSerializeFlags`
* @filename: (type filename): the file to save it to
* @error: Return location for a potential error
*
@@ -867,9 +1522,10 @@ pango_layout_serialize (PangoLayout *layout)
* Since: 1.50
*/
gboolean
-pango_layout_write_to_file (PangoLayout *layout,
- const char *filename,
- GError **error)
+pango_layout_write_to_file (PangoLayout *layout,
+ PangoLayoutSerializeFlags flags,
+ const char *filename,
+ GError **error)
{
GBytes *bytes;
gboolean result;
@@ -878,7 +1534,7 @@ pango_layout_write_to_file (PangoLayout *layout,
g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- bytes = pango_layout_serialize (layout);
+ bytes = pango_layout_serialize (layout, flags);
result = g_file_set_contents (filename,
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes),
@@ -892,6 +1548,7 @@ pango_layout_write_to_file (PangoLayout *layout,
/**
* pango_layout_deserialize:
* @context: a `PangoContext`
+ * @flags: `PangoLayoutDeserializeFlags`
* @bytes: the bytes containing the data
* @error: return location for an error
*
@@ -904,14 +1561,17 @@ pango_layout_write_to_file (PangoLayout *layout,
* Since: 1.50
*/
PangoLayout *
-pango_layout_deserialize (PangoContext *context,
- GBytes *bytes,
- GError **error)
+pango_layout_deserialize (PangoContext *context,
+ GBytes *bytes,
+ PangoLayoutDeserializeFlags flags,
+ GError **error)
{
JsonParser *parser;
JsonNode *node;
PangoLayout *layout;
+ g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
+
parser = json_parser_new_immutable ();
if (!json_parser_load_from_data (parser,
g_bytes_get_data (bytes, NULL),
@@ -923,13 +1583,54 @@ pango_layout_deserialize (PangoContext *context,
}
node = json_parser_get_root (parser);
- layout = json_to_layout (context, node, error);
+ layout = json_to_layout (context, node, flags, error);
g_object_unref (parser);
return layout;
}
+/**
+ * pango_font_serialize:
+ * @font: a `PangoFont`
+ *
+ * Serializes the @font in a way that can be uniquely identified.
+ *
+ * There are no guarantees about the format of the output across different
+ * versions of Pango.
+ *
+ * The intended use of this function is testing, benchmarking and debugging.
+ * The format is not meant as a permanent storage format.
+ *
+ * Returns: a `GBytes` containing the serialized form of @font
+ *
+ * Since: 1.50
+ */
+GBytes *
+pango_font_serialize (PangoFont *font)
+{
+ JsonGenerator *generator;
+ JsonNode *node;
+ char *data;
+ gsize size;
+
+ g_return_val_if_fail (PANGO_IS_FONT (font), NULL);
+
+ node = font_to_json (font);
+
+ generator = json_generator_new ();
+ json_generator_set_pretty (generator, TRUE);
+ json_generator_set_indent (generator, 2);
+
+ json_generator_set_root (generator, node);
+ data = json_generator_to_data (generator, &size);
+
+ json_node_free (node);
+ g_object_unref (generator);
+
+ return g_bytes_new_take (data, size);
+}
+
/* }}} */
/* vim:set foldmethod=marker expandtab: */
diff --git a/pango/shape.c b/pango/shape.c
index 02f0f059..afb1e1a3 100644
--- a/pango/shape.c
+++ b/pango/shape.c
@@ -102,10 +102,12 @@ pango_hb_font_get_nominal_glyph (hb_font_t *font,
* don't draw a hex box for 0x20
*/
if (unicode == 0x20)
- *glyph = PANGO_GET_UNKNOWN_GLYPH (0x2423);
+ unicode = 0x2423;
else
- *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode);
- return TRUE;
+ {
+ *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode);
+ return TRUE;
+ }
}
if ((context->show_flags & PANGO_SHOW_IGNORABLES) != 0 &&
diff --git a/tests/fonts/Cantarell-VF.otf b/tests/fonts/Cantarell-VF.otf
new file mode 100644
index 00000000..cd2ccf42
--- /dev/null
+++ b/tests/fonts/Cantarell-VF.otf
Binary files differ
diff --git a/tests/fonts/DejaVuSans.ttf b/tests/fonts/DejaVuSans.ttf
new file mode 100644
index 00000000..46bb331e
--- /dev/null
+++ b/tests/fonts/DejaVuSans.ttf
Binary files differ
diff --git a/tests/fonts/README b/tests/fonts/README
new file mode 100644
index 00000000..df48f804
--- /dev/null
+++ b/tests/fonts/README
@@ -0,0 +1,4 @@
+The fonts in this directory are available to test-layout tests.
+emoji-subset.ttf is a subset of Noto Color Emoji that is just
+big enough to provide the Emoji that are present in our test
+cases.
diff --git a/tests/fonts/emoji-subset.ttf b/tests/fonts/emoji-subset.ttf
new file mode 100644
index 00000000..2addf727
--- /dev/null
+++ b/tests/fonts/emoji-subset.ttf
Binary files differ
diff --git a/tests/layouts/bratwurst.expected b/tests/layouts/bratwurst.expected
deleted file mode 100644
index f81dbaeb..00000000
--- a/tests/layouts/bratwurst.expected
+++ /dev/null
@@ -1,32 +0,0 @@
-Bratwurst
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 1
-width: 102400
-
---- attributes
-
-range 0 4
-range 4 2147483647
-4 4294967295 style italic
-range 2147483647 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 8(1)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'Bratwurst'
-
---- runs
-
-i=1, index=0, chars=4, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Brat'
-i=2, index=4, chars=5, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'wurst'
-i=3, index=9, no run, line end
diff --git a/tests/layouts/bratwurst.layout b/tests/layouts/bratwurst.layout
index 65104276..c31446ac 100644
--- a/tests/layouts/bratwurst.layout
+++ b/tests/layouts/bratwurst.layout
@@ -1,4 +1,24 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "comment" : [
+ "A case with a single word made up of two items,",
+ "expected to produce a single overlong line."
+ ],
"text" : "Bratwurst",
"attributes" : [
{
@@ -7,15 +27,199 @@
"value" : "italic"
}
],
- "font" : "Sans Bold 32",
- "tabs" : {
- "positions-in-pixels" : true,
- "positions" : [
- 0,
- 50,
- 100
+ "font" : "Cantarell Bold 32",
+ "width" : 87040,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 202752,
+ "height" : 53248,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-boundary" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 9,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 4,
+ "text" : "Brat",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 29,
+ "width" : 28672,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 244,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ }
+ ]
+ },
+ {
+ "offset" : 4,
+ "length" : 5,
+ "text" : "wurst",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 467,
+ "width" : 35840,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 438,
+ "width" : 24576,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 417,
+ "width" : 20480,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ }
+ ]
+ }
]
- },
- "width" : 102400,
- "line-spacing" : 1.2999999523162842
-} \ No newline at end of file
+ }
+}
diff --git a/tests/layouts/bratwurst2.layout b/tests/layouts/bratwurst2.layout
new file mode 100644
index 00000000..ffd37cdd
--- /dev/null
+++ b/tests/layouts/bratwurst2.layout
@@ -0,0 +1,188 @@
+{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "comment" : [
+ "A single word, expected to produce a single",
+ "overlong line."
+ ],
+ "text" : "Bratwurst",
+ "font" : "Cantarell Bold 32",
+ "width" : 87040,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 202752,
+ "height" : 53248,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-boundary" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 9,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 9,
+ "text" : "Bratwurst",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 29,
+ "width" : 28672,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 244,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 467,
+ "width" : 35840,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 438,
+ "width" : 24576,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 417,
+ "width" : 20480,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/layouts/bratwurst3.layout b/tests/layouts/bratwurst3.layout
new file mode 100644
index 00000000..e79ba81c
--- /dev/null
+++ b/tests/layouts/bratwurst3.layout
@@ -0,0 +1,318 @@
+{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "comment" : [
+ "A single word with word-char wrapping,",
+ "expected to be broken to fit the line width."
+ ],
+ "text" : "Bratwurst",
+ "font" : "Cantarell Bold 32",
+ "wrap" : "word-char",
+ "width" : 87040,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 78848,
+ "height" : 212992,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-boundary" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 2,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 2,
+ "text" : "Br",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 4,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 29,
+ "width" : 28672,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1081,
+ "width" : 18432,
+ "log-cluster" : 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 2,
+ "length" : 2,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 2,
+ "length" : 2,
+ "text" : "at",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 4,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1081,
+ "width" : 18432,
+ "log-cluster" : 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 4,
+ "length" : 2,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 4,
+ "length" : 2,
+ "text" : "wu",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 4,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 467,
+ "width" : 35840,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 438,
+ "width" : 24576,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1081,
+ "width" : 18432,
+ "log-cluster" : 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 6,
+ "length" : 3,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 6,
+ "length" : 3,
+ "text" : "rst",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 417,
+ "width" : 20480,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/layouts/bratwurst4.layout b/tests/layouts/bratwurst4.layout
new file mode 100644
index 00000000..f25f1e9e
--- /dev/null
+++ b/tests/layouts/bratwurst4.layout
@@ -0,0 +1,245 @@
+{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "comment" : [
+ "A single word with a soft hyphen,",
+ "expected to be broken at the soft",
+ "hyphen and still produce overlong",
+ "lines."
+ ],
+ "text" : "Brat­wurst",
+ "font" : "Cantarell Bold 32",
+ "width" : 87040,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 115712,
+ "height" : 106496,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-boundary" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 6,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 6,
+ "text" : "Brat­",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 4,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 29,
+ "width" : 28672,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 244,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1081,
+ "width" : 18432,
+ "log-cluster" : 4
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 6,
+ "length" : 5,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 6,
+ "length" : 5,
+ "text" : "wurst",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 467,
+ "width" : 35840,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 438,
+ "width" : 24576,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 417,
+ "width" : 20480,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 430,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/layouts/effigy.layout b/tests/layouts/effigy.layout
new file mode 100644
index 00000000..cc8c4282
--- /dev/null
+++ b/tests/layouts/effigy.layout
@@ -0,0 +1,188 @@
+{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "comment" : [
+ "A ligature that is expected to be borken",
+ "to produce two fitting lines."
+ ],
+ "text" : "effigy",
+ "font" : "DejaVu Sans 32",
+ "wrap" : "char",
+ "width" : 81920,
+ "height" : 2048,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 73728,
+ "height" : 102400,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-boundary" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 3,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 3,
+ "text" : "eff",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "DejaVu Sans 32",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 4,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 72,
+ "width" : 26624,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 5041,
+ "width" : 30720,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 2803,
+ "width" : 16384,
+ "log-cluster" : 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 3,
+ "length" : 3,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 3,
+ "length" : 3,
+ "text" : "igy",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "DejaVu Sans 32",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 76,
+ "width" : 12288,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 74,
+ "width" : 27648,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 92,
+ "width" : 25600,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/layouts/kebab.layout b/tests/layouts/kebab.layout
new file mode 100644
index 00000000..357fd40d
--- /dev/null
+++ b/tests/layouts/kebab.layout
@@ -0,0 +1,254 @@
+{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "comment" : [
+ "Two words, expected to be broken",
+ "between words, collapsing the space",
+ "and still produce two overlong lines."
+ ],
+ "text" : "Döner Kebab",
+ "font" : "Cantarell Bold 32",
+ "width" : 87040,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 126976,
+ "height" : 106496,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-boundary" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 7,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 7,
+ "text" : "Döner ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 37,
+ "width" : 31744,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 381,
+ "width" : 25600,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 360,
+ "width" : 25600,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 287,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 409,
+ "width" : 18432,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 7,
+ "length" : 5,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 7,
+ "length" : 5,
+ "text" : "Kebab",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Bold 32",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 8374
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 100,
+ "width" : 28672,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 272,
+ "width" : 25600,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 244,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 272,
+ "width" : 25600,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/layouts/valid-1.expected b/tests/layouts/valid-1.expected
deleted file mode 100644
index 96bbed57..00000000
--- a/tests/layouts/valid-1.expected
+++ /dev/null
@@ -1,43 +0,0 @@
-This is a test of the automatic emergency brake!
-
---- parameters
-
-wrapped: 0
-ellipsized: 1
-lines: 2
-width: 225280
-
---- attributes
-
-range 0 22
-range 22 41
-22 41 foreground #00000000ffff
-22 41 underline single
-range 41 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 47(1) 49(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'This is a test of the automatic emergency brake!
-'
-i=2, index=49, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=22, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'This is a test of the '
-i=2, index=22, chars=11, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'automatic e'
-22 41 foreground #00000000ffff
-22 41 underline single
-i=3, index=33, chars=15, level=0, gravity=south, flags=2, font=OMITTED, script=common, language=en-us, 'mergency brake!'
-0 2147483647 fallback false
-22 41 foreground #00000000ffff
-22 41 underline single
-i=4, index=48, no run, line end
-i=5, index=49, no run, line end
diff --git a/tests/layouts/valid-1.layout b/tests/layouts/valid-1.layout
index 9289830b..8ee8cf46 100644
--- a/tests/layouts/valid-1.layout
+++ b/tests/layouts/valid-1.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "This is a test of the automatic emergency brake!\n",
"attributes" : [
{
@@ -16,5 +32,660 @@
],
"font" : "Cantarell 11",
"ellipsize" : "end",
- "width" : 225280
+ "width" : 225280,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : true,
+ "unknown-glyphs" : 0,
+ "width" : 225280,
+ "height" : 37888,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 48,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 22,
+ "text" : "This is a test of the ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 187,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ }
+ ]
+ },
+ {
+ "offset" : 22,
+ "length" : 11,
+ "text" : "automatic e",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 22,
+ "end" : 41,
+ "type" : "foreground",
+ "value" : "#00000000ffff"
+ },
+ {
+ "start" : 22,
+ "end" : 41,
+ "type" : "underline",
+ "value" : "single"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 358,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ }
+ ]
+ },
+ {
+ "offset" : 33,
+ "length" : 15,
+ "text" : "mergency brake!",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 2,
+ "extra-attributes" : [
+ {
+ "end" : 2147483647,
+ "type" : "fallback",
+ "value" : false
+ },
+ {
+ "start" : 22,
+ "end" : 41,
+ "type" : "foreground",
+ "value" : "#00000000ffff"
+ },
+ {
+ "start" : 22,
+ "end" : 41,
+ "type" : "underline",
+ "value" : "single"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1062,
+ "width" : 20480,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 49,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-10.expected b/tests/layouts/valid-10.expected
deleted file mode 100644
index 6eb02946..00000000
--- a/tests/layouts/valid-10.expected
+++ /dev/null
@@ -1,37 +0,0 @@
-Hello שלום Γειά σας
-
---- parameters
-
-wrapped: 0
-ellipsized: 1
-lines: 2
-width: 102400
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 12(0) 10(0) 8(0) 14(0) 15(0) 17(0) 19(0) 21(0) 23(0) 24(0) 26(0) 28(0) 28(1) 31(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'Hello שלום Γειά σας
-'
-i=2, index=31, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=6, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Hello '
-i=2, index=12, chars=4, level=1, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, 'שלום'
-i=3, index=14, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, ' '
-i=4, index=15, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=greek, language=el, 'Γ'
-i=5, index=17, chars=7, level=0, gravity=south, flags=2, font=OMITTED, script=common, language=en-us, 'ειά σας'
-0 2147483647 fallback false
-i=6, index=30, no run, line end
-i=7, index=31, no run, line end
diff --git a/tests/layouts/valid-10.layout b/tests/layouts/valid-10.layout
index 0d36a38d..765aba83 100644
--- a/tests/layouts/valid-10.layout
+++ b/tests/layouts/valid-10.layout
@@ -1,8 +1,417 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "Hello שלום Γειά σας\n",
- "attributes" : [],
"font" : "Cantarell 11",
"justify" : true,
"ellipsize" : "end",
- "width" : 102400
+ "width" : 102400,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : true,
+ "unknown-glyphs" : 0,
+ "width" : 102400,
+ "height" : 38912,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "backspace-deletes-character" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 30,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 6,
+ "text" : "Hello ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 76,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ }
+ ]
+ },
+ {
+ "offset" : 6,
+ "length" : 8,
+ "text" : "שלום",
+ "bidi-level" : 1,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1332,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1331,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1344,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 14,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 15,
+ "length" : 2,
+ "text" : "Γ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "el",
+ "script" : "greek",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 677,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 17,
+ "length" : 13,
+ "text" : "ειά σας",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 2,
+ "extra-attributes" : [
+ {
+ "end" : 2147483647,
+ "type" : "fallback",
+ "value" : false
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1062,
+ "width" : 17408,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 31,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-11.expected b/tests/layouts/valid-11.expected
deleted file mode 100644
index c22daf87..00000000
--- a/tests/layouts/valid-11.expected
+++ /dev/null
@@ -1,53 +0,0 @@
-double low error
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-width: 225280
-
---- attributes
-
-range 0 6
-0 6 underline double
-0 6 overline single
-range 6 7
-range 7 10
-7 10 underline low
-7 10 strikethrough true
-range 10 11
-range 11 16
-11 16 underline error
-11 16 rise 1024
-range 16 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 15(1) 17(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'double low error
-'
-i=2, index=17, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=6, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'double'
-0 6 underline double
-0 6 overline single
-i=2, index=6, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' '
-i=3, index=7, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'low'
-7 10 underline low
-7 10 strikethrough true
-i=4, index=10, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' '
-i=5, index=11, chars=5, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'error'
-11 16 rise 1024
-11 16 underline error
-i=6, index=16, no run, line end
-i=7, index=17, no run, line end
diff --git a/tests/layouts/valid-11.layout b/tests/layouts/valid-11.layout
index a044cc53..9a5e5f40 100644
--- a/tests/layouts/valid-11.layout
+++ b/tests/layouts/valid-11.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "double low error\n",
"attributes" : [
{
@@ -38,5 +54,429 @@
],
"font" : "Cantarell 11",
"wrap" : "char",
- "width" : 225280
+ "width" : 225280,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 109568,
+ "height" : 38912,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 16,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 6,
+ "text" : "double",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 6,
+ "type" : "underline",
+ "value" : "double"
+ },
+ {
+ "end" : 6,
+ "type" : "overline",
+ "value" : "single"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ }
+ ]
+ },
+ {
+ "offset" : 6,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 7,
+ "length" : 3,
+ "text" : "low",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 7,
+ "end" : 10,
+ "type" : "underline",
+ "value" : "low"
+ },
+ {
+ "start" : 7,
+ "end" : 10,
+ "type" : "strikethrough",
+ "value" : true
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ },
+ {
+ "offset" : 10,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 11,
+ "length" : 5,
+ "text" : "error",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 11,
+ "end" : 16,
+ "type" : "rise",
+ "value" : 1024
+ },
+ {
+ "start" : 11,
+ "end" : 16,
+ "type" : "underline",
+ "value" : "error"
+ }
+ ],
+ "y-offset" : 1024,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 17,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-12.expected b/tests/layouts/valid-12.expected
deleted file mode 100644
index d66ae134..00000000
--- a/tests/layouts/valid-12.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-a b c d
e f g h
-
---- parameters
-
-wrapped: 1
-ellipsized: 0
-lines: 3
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 25(1) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 50(1) 52(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'a b c d
'
-i=2, index=28, paragraph-start=0, dir=ltr 'e f g h
-'
-i=3, index=52, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=25, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'a b c d'
-i=2, index=25, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '
'
-i=3, index=28, no run, line end
-i=4, index=28, chars=23, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'e f g h'
-i=5, index=51, no run, line end
-i=6, index=52, no run, line end
diff --git a/tests/layouts/valid-12.layout b/tests/layouts/valid-12.layout
index 1c9fa227..59451e08 100644
--- a/tests/layouts/valid-12.layout
+++ b/tests/layouts/valid-12.layout
@@ -1,6 +1,21 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "a b c d
e f g h\n",
- "attributes" : [],
"font" : "Cantarell 11",
"tabs" : {
"positions-in-pixels" : true,
@@ -11,5 +26,763 @@
150,
200
]
+ },
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 1,
+ "width" : 113664,
+ "height" : 56320,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 28,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 25,
+ "text" : "a b c d",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ }
+ ]
+ },
+ {
+ "offset" : 25,
+ "length" : 3,
+ "text" : "
",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 268443688,
+ "width" : 17408,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 28,
+ "length" : 23,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 28,
+ "length" : 23,
+ "text" : "e f g h",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 52,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
}
}
diff --git a/tests/layouts/valid-13.expected b/tests/layouts/valid-13.expected
deleted file mode 100644
index cc435a88..00000000
--- a/tests/layouts/valid-13.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-a b c d
e f g h
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 1
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 51(1)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'a b c d
e f g h
-'
-
---- runs
-
-i=1, index=0, chars=25, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'a b c d'
-0 4294967295 show 2
-i=2, index=25, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '
'
-0 4294967295 show 2
-i=3, index=28, chars=24, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'e f g h
-'
-0 4294967295 show 2
-i=4, index=52, no run, line end
diff --git a/tests/layouts/valid-13.layout b/tests/layouts/valid-13.layout
index a9f10f86..b3aaeb1c 100644
--- a/tests/layouts/valid-13.layout
+++ b/tests/layouts/valid-13.layout
@@ -1,6 +1,21 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "a b c d
e f g h\n",
- "attributes" : [],
"font" : "Cantarell 11",
"tabs" : {
"positions-in-pixels" : true,
@@ -12,5 +27,772 @@
200
]
},
- "single-paragraph" : true
+ "single-paragraph" : true,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 2,
+ "width" : 219136,
+ "height" : 18432,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 52,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 25,
+ "text" : "a b c d",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "type" : "show",
+ "value" : 2
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ }
+ ]
+ },
+ {
+ "offset" : 25,
+ "length" : 3,
+ "text" : "
",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "type" : "show",
+ "value" : 2
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 268443688,
+ "width" : 17408,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 28,
+ "length" : 24,
+ "text" : "e f g h\n",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "type" : "show",
+ "value" : 2
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 268435466,
+ "width" : 17408,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-14.expected b/tests/layouts/valid-14.expected
deleted file mode 100644
index 89172781..00000000
--- a/tests/layouts/valid-14.expected
+++ /dev/null
@@ -1,38 +0,0 @@
-你好 Hello שלום Γειά σας
-
---- parameters
-
-wrapped: 0
-ellipsized: 1
-lines: 2
-width: 161792
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 3(0) 6(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 19(0) 17(0) 15(0) 21(0) 22(0) 24(0) 26(0) 28(0) 30(0) 31(0) 33(0) 35(0) 35(1) 38(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr '你好 Hello שלום Γειά σας
-'
-i=2, index=38, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=1, level=0, gravity=south, flags=2, font=OMITTED, script=common, language=en-us, '你'
-0 2147483647 fallback true
-i=2, index=3, chars=2, level=0, gravity=south, flags=0, font=OMITTED, script=han, language=xx, '好 '
-i=3, index=7, chars=6, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Hello '
-i=4, index=19, chars=4, level=1, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, 'שלום'
-i=5, index=21, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, ' '
-i=6, index=22, chars=8, level=0, gravity=south, flags=0, font=OMITTED, script=greek, language=el, 'Γειά σας'
-i=7, index=37, no run, line end
-i=8, index=38, no run, line end
diff --git a/tests/layouts/valid-14.layout b/tests/layouts/valid-14.layout
index 116cc94f..61e7182e 100644
--- a/tests/layouts/valid-14.layout
+++ b/tests/layouts/valid-14.layout
@@ -1,8 +1,528 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "你好 Hello שלום Γειά σας\n",
- "attributes" : [],
"font" : "Cantarell 11",
"ellipsize" : "start",
"width" : 161792,
- "line-spacing" : 1.5
+ "line-spacing" : 1.5,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : true,
+ "unknown-glyphs" : 0,
+ "width" : 161792,
+ "height" : 47104,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "backspace-deletes-character" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "backspace-deletes-character" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 37,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 6,
+ "text" : "你好",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 2,
+ "extra-attributes" : [
+ {
+ "end" : 2147483647,
+ "type" : "fallback",
+ "value" : true
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1058,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1058,
+ "width" : 4096,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1058,
+ "width" : 16384,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 6,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "xx",
+ "script" : "han",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 7,
+ "length" : 6,
+ "text" : "Hello ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 76,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ }
+ ]
+ },
+ {
+ "offset" : 13,
+ "length" : 8,
+ "text" : "שלום",
+ "bidi-level" : 1,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1332,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1331,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1344,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 21,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 22,
+ "length" : 15,
+ "text" : "Γειά σας",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "el",
+ "script" : "greek",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 677,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 808,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 812,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 837,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 822,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 804,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 821,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 38,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-15.expected b/tests/layouts/valid-15.expected
deleted file mode 100644
index f029482a..00000000
--- a/tests/layouts/valid-15.expected
+++ /dev/null
@@ -1,36 +0,0 @@
-Lets see if this text is long enough to wrap due to height limitations. It might, or it might not.
-
---- parameters
-
-wrapped: 1
-ellipsized: 1
-lines: 2
-width: 153600
-height: 40960
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 24(1) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 52(0) 53(0) 54(0) 55(0) 56(0) 57(0) 58(0) 59(0) 60(0) 61(0) 62(0) 63(0) 64(0) 65(0) 66(0) 67(0) 68(0) 69(0) 70(0) 71(0) 72(0) 73(0) 74(0) 75(0) 76(0) 77(0) 78(0) 79(0) 80(0) 81(0) 82(0) 83(0) 84(0) 85(0) 86(0) 87(0) 88(0) 89(0) 90(0) 91(0) 92(0) 93(0) 94(0) 95(0) 96(0) 97(0) 97(1)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'Lets see if this text is '
-i=2, index=25, paragraph-start=0, dir=ltr 'long enough to wrap due to height limitations. It might, or it might not.
-'
-
---- runs
-
-i=1, index=0, chars=25, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Lets see if this text is '
-i=2, index=25, no run, line end
-i=3, index=25, chars=20, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'long enough to wrap '
-i=4, index=45, chars=53, level=0, gravity=south, flags=2, font=OMITTED, script=common, language=en-us, 'due to height limitations. It might, or it might not.'
-0 2147483647 fallback false
-i=5, index=98, no run, line end
diff --git a/tests/layouts/valid-15.layout b/tests/layouts/valid-15.layout
index 9f584ba6..b6613068 100644
--- a/tests/layouts/valid-15.layout
+++ b/tests/layouts/valid-15.layout
@@ -1,8 +1,1033 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "Lets see if this text is long enough to wrap due to height limitations. It might, or it might not.\n",
- "attributes" : [],
"font" : "Cantarell 11",
"ellipsize" : "end",
"width" : 153600,
- "height" : 40960
+ "height" : 40960,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : true,
+ "unknown-glyphs" : 0,
+ "width" : 153600,
+ "height" : 36864,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 25,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 25,
+ "text" : "Lets see if this text is ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 103,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 472,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 25,
+ "length" : 73,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 25,
+ "length" : 20,
+ "text" : "long enough to wrap ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ }
+ ]
+ },
+ {
+ "offset" : 45,
+ "length" : 53,
+ "text" : "due to height limitations. It might, or it might not.",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 2,
+ "extra-attributes" : [
+ {
+ "end" : 2147483647,
+ "type" : "fallback",
+ "value" : false
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1062,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-16.expected b/tests/layouts/valid-16.expected
deleted file mode 100644
index 01af96cf..00000000
--- a/tests/layouts/valid-16.expected
+++ /dev/null
@@ -1,37 +0,0 @@
-Lets see if this text is long enough to wrap due to height limitations. It might, or it might not.
-
---- parameters
-
-wrapped: 1
-ellipsized: 1
-lines: 3
-width: 153600
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 24(1) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 52(0) 53(0) 54(0) 55(0) 56(0) 57(0) 58(0) 59(0) 60(0) 61(0) 62(0) 63(0) 64(0) 65(0) 66(0) 67(0) 68(0) 69(0) 70(0) 71(0) 72(0) 73(0) 74(0) 75(0) 76(0) 77(0) 78(0) 79(0) 80(0) 81(0) 82(0) 83(0) 84(0) 85(0) 86(0) 87(0) 88(0) 89(0) 90(0) 91(0) 92(0) 93(0) 94(0) 95(0) 96(0) 97(0) 97(1) 99(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'Lets see if this text is '
-i=2, index=25, paragraph-start=0, dir=ltr 'long enough to wrap due to height limitations. It might, or it might not.
-'
-i=3, index=99, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=25, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Lets see if this text is '
-i=2, index=25, no run, line end
-i=3, index=25, chars=20, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'long enough to wrap '
-i=4, index=45, chars=53, level=0, gravity=south, flags=2, font=OMITTED, script=common, language=en-us, 'due to height limitations. It might, or it might not.'
-0 2147483647 fallback false
-i=5, index=98, no run, line end
-i=6, index=99, no run, line end
diff --git a/tests/layouts/valid-16.layout b/tests/layouts/valid-16.layout
index e2a82d96..fc2776e2 100644
--- a/tests/layouts/valid-16.layout
+++ b/tests/layouts/valid-16.layout
@@ -1,9 +1,1041 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "Lets see if this text is long enough to wrap due to height limitations. It might, or it might not.\n",
- "attributes" : [],
"font" : "Cantarell 11",
"wrap" : "word-char",
"ellipsize" : "end",
"width" : 153600,
- "height" : -2
+ "height" : -2,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : true,
+ "unknown-glyphs" : 0,
+ "width" : 153600,
+ "height" : 56320,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 25,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 25,
+ "text" : "Lets see if this text is ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 103,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 472,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 25,
+ "length" : 73,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 25,
+ "length" : 20,
+ "text" : "long enough to wrap ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ }
+ ]
+ },
+ {
+ "offset" : 45,
+ "length" : 53,
+ "text" : "due to height limitations. It might, or it might not.",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 2,
+ "extra-attributes" : [
+ {
+ "end" : 2147483647,
+ "type" : "fallback",
+ "value" : false
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1062,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 99,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-17.expected b/tests/layouts/valid-17.expected
deleted file mode 100644
index 4b3192fb..00000000
--- a/tests/layouts/valid-17.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-some|bla|bla|bla
-
---- parameters
-
-wrapped: 1
-ellipsized: 0
-lines: 3
-width: 102400
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 12(1) 14(0) 15(0) 15(1) 17(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'some|bla|bla|'
-i=2, index=13, paragraph-start=0, dir=ltr 'bla
-'
-i=3, index=17, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=13, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'some|bla|bla|'
-i=2, index=13, no run, line end
-i=3, index=13, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'bla'
-i=4, index=16, no run, line end
-i=5, index=17, no run, line end
diff --git a/tests/layouts/valid-17.layout b/tests/layouts/valid-17.layout
index 062cc241..71182844 100644
--- a/tests/layouts/valid-17.layout
+++ b/tests/layouts/valid-17.layout
@@ -1,7 +1,335 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "some|bla|bla|bla\n",
- "attributes" : [],
"font" : "Cantarell 11",
"justify" : true,
- "width" : 102400
+ "width" : 102400,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 102400,
+ "height" : 56320,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 13,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 13,
+ "text" : "some|bla|bla|",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 370,
+ "width" : 9216,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 358,
+ "width" : 14336,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 287,
+ "width" : 9216,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1188,
+ "width" : 5120,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 272,
+ "width" : 9216,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 349,
+ "width" : 5120,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 244,
+ "width" : 9216,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 1188,
+ "width" : 5120,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 272,
+ "width" : 9216,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 349,
+ "width" : 5120,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 244,
+ "width" : 9216,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 1188,
+ "width" : 5120,
+ "x-offset" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 13,
+ "length" : 3,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 13,
+ "length" : 3,
+ "text" : "bla",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 17,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-18.expected b/tests/layouts/valid-18.expected
deleted file mode 100644
index ea6aabeb..00000000
--- a/tests/layouts/valid-18.expected
+++ /dev/null
@@ -1,40 +0,0 @@
-some line breaks
and mis­ce­llaneous ignora‌bles
-
---- parameters
-
-wrapped: 1
-ellipsized: 0
-lines: 3
-
---- attributes
-
-range 0 57
-0 57 show 7
-range 57 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 16(1) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 26(0) 28(0) 29(0) 30(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 46(0) 47(0) 48(0) 49(0) 53(0) 54(0) 55(0) 56(0) 56(1) 58(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'some line breaks
'
-i=2, index=19, paragraph-start=0, dir=ltr 'and mis­ce­llaneous ignora‌bles
-'
-i=3, index=58, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=16, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'some line breaks'
-0 57 show 7
-i=2, index=16, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '
'
-0 57 show 7
-i=3, index=19, no run, line end
-i=4, index=19, chars=32, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'and mis­ce­llaneous ignora‌bles'
-0 57 show 7
-i=5, index=57, no run, line end
-i=6, index=58, no run, line end
diff --git a/tests/layouts/valid-18.layout b/tests/layouts/valid-18.layout
index 85e9a7d1..2337a562 100644
--- a/tests/layouts/valid-18.layout
+++ b/tests/layouts/valid-18.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "some line breaks
and mis­ce­llaneous ignora‌bles\n",
"attributes" : [
{
@@ -7,5 +23,741 @@
"value" : 7
}
],
- "font" : "Cantarell 11"
+ "font" : "Cantarell 11",
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 5,
+ "width" : 302080,
+ "height" : 56320,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 19,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 16,
+ "text" : "some line breaks",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 57,
+ "type" : "show",
+ "value" : 7
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 358,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1195,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1195,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 345,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ }
+ ]
+ },
+ {
+ "offset" : 16,
+ "length" : 3,
+ "text" : "
",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 57,
+ "type" : "show",
+ "value" : 7
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 268443688,
+ "width" : 17408,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 19,
+ "length" : 38,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 19,
+ "length" : 38,
+ "text" : "and mis­ce­llaneous ignora‌bles",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 57,
+ "type" : "show",
+ "value" : 7
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1195,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 358,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 268435629,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 268435629,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1195,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 268500735,
+ "width" : 23552,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 27
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 28
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 29
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 30
+ },
+ {
+ "glyph" : 268443660,
+ "width" : 17408,
+ "is-cluster-start" : true,
+ "log-cluster" : 31
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 34
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 35
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 36
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 37
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 58,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-19.expected b/tests/layouts/valid-19.expected
deleted file mode 100644
index 5e115e47..00000000
--- a/tests/layouts/valid-19.expected
+++ /dev/null
@@ -1,42 +0,0 @@
- a⃠ 😊︎ 😊️ 🇩🇪 ✊ ✋🏾 0 # 🏴󠁵󠁳󠁣󠁡󠁿 ©
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 5(0) 6(0) 13(0) 14(0) 21(0) 22(0) 30(0) 31(0) 34(0) 35(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 71(0) 72(0) 72(1) 75(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr ' a⃠ 😊︎ 😊️ 🇩🇪 ✊ ✋🏾 0 # 🏴󠁵󠁳󠁣󠁡󠁿 ©
-'
-i=2, index=75, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=4, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' a⃠ '
-i=2, index=6, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '😊︎ '
-i=3, index=14, chars=2, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '😊️'
-i=4, index=21, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' '
-i=5, index=22, chars=2, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '🇩🇪'
-i=6, index=30, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' '
-i=7, index=31, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '✊'
-i=8, index=34, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' '
-i=9, index=35, chars=2, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '✋🏾'
-i=10, index=42, chars=5, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' 0 # '
-i=11, index=47, chars=6, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '🏴󠁵󠁳󠁣󠁡󠁿'
-i=12, index=71, chars=2, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' ©'
-i=13, index=74, no run, line end
-i=14, index=75, no run, line end
diff --git a/tests/layouts/valid-19.layout b/tests/layouts/valid-19.layout
index 32ad1283..c9e6d979 100644
--- a/tests/layouts/valid-19.layout
+++ b/tests/layouts/valid-19.layout
@@ -1,5 +1,617 @@
{
- "text" : " a⃠ 😊︎ 😊️ 🇩🇪 ✊ ✋🏾 0 # 🏴󠁵󠁳󠁣󠁡󠁿 ©\n",
- "attributes" : [],
- "font" : "Cantarell 11"
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "text" : "😊︎ 😊️ 🇩🇪 ✊ ✋🏾 0 # 🏴󠁵󠁳󠁣󠁡󠁿 ©\n",
+ "font" : "Cantarell 11",
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 649216,
+ "height" : 150528,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ { },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ { },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ { },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ { },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ { },
+ { },
+ { },
+ { },
+ { },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 68,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 8,
+ "text" : "😊︎ ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 5867,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 3,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ }
+ ]
+ },
+ {
+ "offset" : 8,
+ "length" : 7,
+ "text" : "😊️",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 5867,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ },
+ {
+ "offset" : 15,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 16,
+ "length" : 8,
+ "text" : "🇩🇪",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Noto Color Emoji 11",
+ "checksum" : "cc2ce7351378d5dfa4fce6fd8619e5dcf73693d0089e9223c54e3926cdb8a531",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 20,
+ "width" : 139264,
+ "is-cluster-start" : true,
+ "is-color" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 24,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 25,
+ "length" : 3,
+ "text" : "✊",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Noto Color Emoji 11",
+ "checksum" : "cc2ce7351378d5dfa4fce6fd8619e5dcf73693d0089e9223c54e3926cdb8a531",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 5,
+ "width" : 139264,
+ "is-cluster-start" : true,
+ "is-color" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 28,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 29,
+ "length" : 7,
+ "text" : "✋🏾",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Noto Color Emoji 11",
+ "checksum" : "cc2ce7351378d5dfa4fce6fd8619e5dcf73693d0089e9223c54e3926cdb8a531",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 19,
+ "width" : 139264,
+ "is-cluster-start" : true,
+ "is-color" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 36,
+ "length" : 5,
+ "text" : " 0 # ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 964,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1070,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ },
+ {
+ "offset" : 41,
+ "length" : 24,
+ "text" : "🏴󠁵󠁳󠁣󠁡󠁿",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Noto Color Emoji 11",
+ "checksum" : "cc2ce7351378d5dfa4fce6fd8619e5dcf73693d0089e9223c54e3926cdb8a531",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 22,
+ "width" : 139264,
+ "is-cluster-start" : true,
+ "is-color" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 65,
+ "length" : 3,
+ "text" : " ©",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1182,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 69,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-2.expected b/tests/layouts/valid-2.expected
deleted file mode 100644
index 76c4f453..00000000
--- a/tests/layouts/valid-2.expected
+++ /dev/null
@@ -1,42 +0,0 @@
-test the blue drink after dinner
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-
---- attributes
-
-range 0 9
-range 9 13
-9 13 style italic
-range 13 20
-range 20 25
-20 25 underline single
-range 25 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 31(1) 33(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'test the blue drink after dinner
-'
-i=2, index=33, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=9, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'test the '
-i=2, index=9, chars=4, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'blue'
-i=3, index=13, chars=7, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' drink '
-i=4, index=20, chars=5, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'after'
-20 25 underline single
-i=5, index=25, chars=7, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' dinner'
-i=6, index=32, no run, line end
-i=7, index=33, no run, line end
diff --git a/tests/layouts/valid-2.layout b/tests/layouts/valid-2.layout
index 303b2b67..7e8fb961 100644
--- a/tests/layouts/valid-2.layout
+++ b/tests/layouts/valid-2.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "test the blue drink after dinner\n",
"attributes" : [
{
@@ -14,5 +30,588 @@
"value" : "single"
}
],
- "font" : "Cantarell 11"
+ "font" : "Cantarell 11",
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 200704,
+ "height" : 37888,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 32,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 9,
+ "text" : "test the ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ }
+ ]
+ },
+ {
+ "offset" : 9,
+ "length" : 4,
+ "text" : "blue",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ }
+ ]
+ },
+ {
+ "offset" : 13,
+ "length" : 7,
+ "text" : " drink ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 345,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ }
+ ]
+ },
+ {
+ "offset" : 20,
+ "length" : 5,
+ "text" : "after",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 20,
+ "end" : 25,
+ "type" : "underline",
+ "value" : "single"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ },
+ {
+ "offset" : 25,
+ "length" : 7,
+ "text" : " dinner",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 33,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-20.expected b/tests/layouts/valid-20.expected
deleted file mode 100644
index e3a68815..00000000
--- a/tests/layouts/valid-20.expected
+++ /dev/null
@@ -1,40 +0,0 @@
-abcdef
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-
---- attributes
-
-range 0 3
-0 3 gravity east
-0 3 gravity-hint strong
-range 3 6
-3 6 gravity south
-range 6 2147483647
-
---- directions
-
-0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 5(1) 7(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'abcdef
-'
-i=2, index=7, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=3, level=0, gravity=east, flags=0, font=OMITTED, script=latin, language=en-us, 'abc'
-0 3 gravity east
-0 3 gravity-hint strong
-i=2, index=3, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'def'
-3 6 gravity south
-i=3, index=6, no run, line end
-i=4, index=7, no run, line end
diff --git a/tests/layouts/valid-20.layout b/tests/layouts/valid-20.layout
index bde84b6f..1be94175 100644
--- a/tests/layouts/valid-20.layout
+++ b/tests/layouts/valid-20.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "abcdef\n",
"attributes" : [
{
@@ -18,5 +34,205 @@
"value" : "south"
}
],
- "font" : "Cantarell 11"
+ "font" : "Cantarell 11",
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 76800,
+ "height" : 44032,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 6,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 3,
+ "text" : "abc",
+ "bidi-level" : 0,
+ "gravity" : "east",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell Rotated-Left 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 3,
+ "type" : "gravity",
+ "value" : "east"
+ },
+ {
+ "end" : 3,
+ "type" : "gravity-hint",
+ "value" : "strong"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 18432,
+ "x-offset" : 33196,
+ "y-offset" : 3844,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 272,
+ "width" : 18432,
+ "x-offset" : 33196,
+ "y-offset" : 4280,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 273,
+ "width" : 18432,
+ "x-offset" : 33196,
+ "y-offset" : 3506,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ },
+ {
+ "offset" : 3,
+ "length" : 3,
+ "text" : "def",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 3,
+ "end" : 6,
+ "type" : "gravity",
+ "value" : "south"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 7,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-22.expected b/tests/layouts/valid-22.expected
deleted file mode 100644
index 8bbd3620..00000000
--- a/tests/layouts/valid-22.expected
+++ /dev/null
@@ -1,111 +0,0 @@
-e0 = ooo...
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-
---- attributes
-
-range 0 1
-range 1 2
-1 2 font-desc "Italic"
-1 2 font-scale subscript
-1 2 baseline-shift subscript
-range 2 6
-range 6 7
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-range 7 8
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-range 8 9
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-8 11 font-scale superscript
-8 11 baseline-shift superscript
-range 9 10
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-8 11 font-scale superscript
-8 11 baseline-shift superscript
-9 11 font-scale superscript
-9 11 baseline-shift superscript
-range 10 11
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-8 11 font-scale superscript
-8 11 baseline-shift superscript
-9 11 font-scale superscript
-9 11 baseline-shift superscript
-10 11 font-scale superscript
-10 11 baseline-shift superscript
-range 11 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(1) 12(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'e0 = ooo...
-'
-i=2, index=12, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'e'
-i=2, index=1, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '0'
-1 2 font-scale subscript
-1 2 baseline-shift subscript
-i=3, index=2, chars=4, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' = o'
-i=4, index=6, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'o'
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-i=5, index=7, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'o'
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-i=6, index=8, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '.'
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-8 11 font-scale superscript
-8 11 baseline-shift superscript
-i=7, index=9, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '.'
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-8 11 font-scale superscript
-8 11 baseline-shift superscript
-9 11 font-scale superscript
-9 11 baseline-shift superscript
-i=8, index=10, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '.'
-6 11 font-scale superscript
-6 11 baseline-shift superscript
-7 11 font-scale superscript
-7 11 baseline-shift superscript
-8 11 font-scale superscript
-8 11 baseline-shift superscript
-9 11 font-scale superscript
-9 11 baseline-shift superscript
-10 11 font-scale superscript
-10 11 baseline-shift superscript
-i=9, index=11, no run, line end
-i=10, index=12, no run, line end
diff --git a/tests/layouts/valid-22.layout b/tests/layouts/valid-22.layout
index be57d26a..615200cb 100644
--- a/tests/layouts/valid-22.layout
+++ b/tests/layouts/valid-22.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "e0 = ooo...\n",
"attributes" : [
{
@@ -80,5 +96,626 @@
"value" : "superscript"
}
],
- "font" : "Cantarell 11"
+ "font" : "Cantarell 11",
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 49152,
+ "height" : 41090,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 11,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 1,
+ "text" : "e",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 1,
+ "length" : 1,
+ "text" : "0",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 7.1484375",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 1,
+ "end" : 2,
+ "type" : "font-scale",
+ "value" : "subscript"
+ },
+ {
+ "start" : 1,
+ "end" : 2,
+ "type" : "baseline-shift",
+ "value" : "subscript"
+ }
+ ],
+ "y-offset" : -3274,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 964,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 2,
+ "length" : 4,
+ "text" : " = o",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1147,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ }
+ ]
+ },
+ {
+ "offset" : 6,
+ "length" : 1,
+ "text" : "o",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 7.1484375",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ }
+ ],
+ "y-offset" : 5542,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 370,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 7,
+ "length" : 1,
+ "text" : "o",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 4.646484375",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ }
+ ],
+ "y-offset" : 9144,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 370,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 8,
+ "length" : 1,
+ "text" : ".",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 3.0205078125",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 8,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 8,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ }
+ ],
+ "y-offset" : 11485,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1058,
+ "width" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 9,
+ "length" : 1,
+ "text" : ".",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 1.962890625",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 8,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 8,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 9,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 9,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ }
+ ],
+ "y-offset" : 13007,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1058,
+ "width" : 1024,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 10,
+ "length" : 1,
+ "text" : ".",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 1.2763671875",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 6,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 7,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 8,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 8,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 9,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 9,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ },
+ {
+ "start" : 10,
+ "end" : 11,
+ "type" : "font-scale",
+ "value" : "superscript"
+ },
+ {
+ "start" : 10,
+ "end" : 11,
+ "type" : "baseline-shift",
+ "value" : "superscript"
+ }
+ ],
+ "y-offset" : 13996,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1058,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 12,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-3.expected b/tests/layouts/valid-3.expected
deleted file mode 100644
index d090bac0..00000000
--- a/tests/layouts/valid-3.expected
+++ /dev/null
@@ -1,33 +0,0 @@
-ABC😀️D
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 10(0) 10(1) 12(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'ABC😀️D
-'
-i=2, index=12, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ABC'
-i=2, index=3, chars=2, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '😀️'
-i=3, index=10, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'D'
-i=4, index=11, no run, line end
-i=5, index=12, no run, line end
diff --git a/tests/layouts/valid-3.layout b/tests/layouts/valid-3.layout
index ef1b1917..c11c2b35 100644
--- a/tests/layouts/valid-3.layout
+++ b/tests/layouts/valid-3.layout
@@ -1,5 +1,221 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "ABC😀️D\n",
- "attributes" : [],
- "font" : "Cantarell 11"
+ "font" : "Cantarell 11",
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 54272,
+ "height" : 38912,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ { },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 11,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 3,
+ "text" : "ABC",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 29,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 30,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ },
+ {
+ "offset" : 3,
+ "length" : 7,
+ "text" : "😀️",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 5857,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ },
+ {
+ "offset" : 10,
+ "length" : 1,
+ "text" : "D",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 37,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 12,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-4.expected b/tests/layouts/valid-4.expected
deleted file mode 100644
index 4e69d61d..00000000
--- a/tests/layouts/valid-4.expected
+++ /dev/null
@@ -1,44 +0,0 @@
-This paragraph should ac­tual­ly have multiple lines, unlike all the other wannabe äöü pa­ra­graph tests in this ugh test-case. Grow some lines!
-
---- parameters
-
-wrapped: 1
-ellipsized: 0
-lines: 6
-width: 198656
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 27(0) 28(0) 29(0) 30(0) 30(1) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 52(0) 53(0) 54(0) 55(0) 56(0) 57(0) 58(0) 59(0) 60(0) 61(0) 62(0) 62(1) 64(0) 65(0) 66(0) 67(0) 68(0) 69(0) 70(0) 71(0) 72(0) 73(0) 74(0) 75(0) 76(0) 77(0) 78(0) 79(0) 80(0) 81(0) 82(0) 83(0) 84(0) 85(0) 87(0) 89(0) 91(0) 92(0) 93(0) 94(0) 94(1) 97(0) 98(0) 101(0) 102(0) 103(0) 104(0) 105(0) 106(0) 107(0) 108(0) 109(0) 110(0) 111(0) 112(0) 113(0) 114(0) 115(0) 116(0) 117(0) 118(0) 119(0) 120(0) 121(0) 122(0) 123(0) 124(0) 125(0) 126(0) 127(0) 128(0) 128(1) 130(0) 131(0) 132(0) 133(0) 134(0) 135(0) 136(0) 137(0) 138(0) 139(0) 140(0) 141(0) 142(0) 143(0) 144(0) 145(0) 146(0) 147(0) 148(0) 149(0) 150(0) 150(1) 152(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'This paragraph should ac­tual­'
-i=2, index=32, paragraph-start=0, dir=ltr 'ly have multiple lines, unlike '
-i=3, index=63, paragraph-start=0, dir=ltr 'all the other wannabe äöü pa­'
-i=4, index=96, paragraph-start=0, dir=ltr 'ra­graph tests in this ugh test-'
-i=5, index=129, paragraph-start=0, dir=ltr 'case. Grow some lines!
-'
-i=6, index=152, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=30, level=0, gravity=south, flags=4, font=OMITTED, script=latin, language=en-us, 'This paragraph should ac­tual­'
-i=2, index=32, no run, line end
-i=3, index=32, chars=31, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ly have multiple lines, unlike '
-i=4, index=63, no run, line end
-i=5, index=63, chars=29, level=0, gravity=south, flags=4, font=OMITTED, script=latin, language=en-us, 'all the other wannabe äöü pa­'
-i=6, index=96, no run, line end
-i=7, index=96, chars=32, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ra­graph tests in this ugh test-'
-i=8, index=129, no run, line end
-i=9, index=129, chars=22, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'case. Grow some lines!'
-i=10, index=151, no run, line end
-i=11, index=152, no run, line end
diff --git a/tests/layouts/valid-4.layout b/tests/layouts/valid-4.layout
index 5504107d..e4358637 100644
--- a/tests/layouts/valid-4.layout
+++ b/tests/layouts/valid-4.layout
@@ -1,6 +1,1960 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "This paragraph should ac­tual­ly have multiple lines, unlike all the other wannabe äöü pa­ra­graph tests in this ugh test-case. Grow some lines!\n",
- "attributes" : [],
"font" : "Cantarell 11",
- "width" : 198656
+ "width" : 198656,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 197632,
+ "height" : 111616,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 32,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 32,
+ "text" : "This paragraph should ac­tual­",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 4,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 187,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 26
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 27
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 28
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 29
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 30
+ },
+ {
+ "glyph" : 1081,
+ "width" : 6144,
+ "log-cluster" : 30
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 32,
+ "length" : 31,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 32,
+ "length" : 31,
+ "text" : "ly have multiple lines, unlike ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 473,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 466,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 358,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 1059,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 25
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 26
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 27
+ },
+ {
+ "glyph" : 345,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 28
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 29
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 30
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 63,
+ "length" : 33,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 63,
+ "length" : 33,
+ "text" : "all the other wannabe äöü pa­",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 4,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 260,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 381,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ },
+ {
+ "glyph" : 444,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 26
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 28
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 29
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 30
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 31
+ },
+ {
+ "glyph" : 1081,
+ "width" : 6144,
+ "log-cluster" : 31
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 96,
+ "length" : 33,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 96,
+ "length" : 33,
+ "text" : "ra­graph tests in this ugh test-",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 25
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 26
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 27
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 28
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 29
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 30
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 31
+ },
+ {
+ "glyph" : 1081,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 32
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 129,
+ "length" : 22,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 129,
+ "length" : 22,
+ "text" : "case. Grow some lines!",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1058,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 69,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 358,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1063,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 152,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-5.expected b/tests/layouts/valid-5.expected
deleted file mode 100644
index 20627955..00000000
--- a/tests/layouts/valid-5.expected
+++ /dev/null
@@ -1,56 +0,0 @@
-A test with multiple paragraphs and with no-break attributes, which might trigger a crash.
-If it doesn't the fix has worked.
-
---- parameters
-
-wrapped: 1
-ellipsized: 0
-lines: 7
-width: 194560
-
---- attributes
-
-range 0 21
-range 21 31
-21 31 font-features "tnum=1"
-range 31 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 20(1) 22(0) 23(0) 24(0) 25(0) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 43(1) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 52(0) 53(0) 54(0) 55(0) 56(0) 57(0) 58(0) 59(0) 60(0) 61(0) 62(0) 63(0) 64(0) 65(0) 66(0) 67(0) 68(0) 69(0) 70(0) 71(0) 72(0) 73(0) 73(1) 75(0) 76(0) 77(0) 78(0) 79(0) 80(0) 81(0) 82(0) 83(0) 84(0) 85(0) 86(0) 87(0) 88(0) 89(0) 89(1) 91(0) 92(0) 93(0) 94(0) 95(0) 96(0) 97(0) 98(0) 99(0) 100(0) 101(0) 102(0) 103(0) 104(0) 105(0) 106(0) 107(0) 108(0) 109(0) 110(0) 111(0) 112(0) 113(0) 114(0) 115(0) 116(0) 116(1) 118(0) 119(0) 120(0) 121(0) 122(0) 123(0) 123(1) 125(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'A test with multiple '
-i=2, index=21, paragraph-start=0, dir=ltr 'paragraphs and with no-'
-i=3, index=44, paragraph-start=0, dir=ltr 'break attributes, which might '
-i=4, index=74, paragraph-start=0, dir=ltr 'trigger a crash.
-'
-i=5, index=91, paragraph-start=1, dir=ltr 'If it doesn't the fix has '
-i=6, index=117, paragraph-start=0, dir=ltr 'worked.
-'
-i=7, index=125, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=21, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'A test with multiple '
-21 31 font-features "tnum=1"
-i=2, index=21, no run, line end
-i=3, index=21, chars=23, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'paragraphs and with no-'
-21 31 font-features "tnum=1"
-i=4, index=44, no run, line end
-i=5, index=44, chars=30, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'break attributes, which might '
-21 31 font-features "tnum=1"
-i=6, index=74, no run, line end
-i=7, index=74, chars=16, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'trigger a crash.'
-21 31 font-features "tnum=1"
-i=8, index=90, no run, line end
-i=9, index=91, chars=26, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'If it doesn't the fix has '
-i=10, index=117, no run, line end
-i=11, index=117, chars=7, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'worked.'
-i=12, index=124, no run, line end
-i=13, index=125, no run, line end
diff --git a/tests/layouts/valid-5.layout b/tests/layouts/valid-5.layout
index e5e96b9a..a861ab30 100644
--- a/tests/layouts/valid-5.layout
+++ b/tests/layouts/valid-5.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "A test with multiple paragraphs and with no-break attributes, which might trigger a crash.\nIf it doesn't the fix has worked.\n",
"attributes" : [
{
@@ -9,5 +25,1764 @@
}
],
"font" : "Cantarell 11",
- "width" : 194560
+ "width" : 194560,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 194560,
+ "height" : 130048,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 21,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 21,
+ "text" : "A test with multiple ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 21,
+ "end" : 31,
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 358,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 21,
+ "length" : 23,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 21,
+ "length" : 23,
+ "text" : "paragraphs and with no-",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 21,
+ "end" : 31,
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 1081,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 44,
+ "length" : 30,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 44,
+ "length" : 30,
+ "text" : "break attributes, which might ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 21,
+ "end" : 31,
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 345,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 438,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 1059,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 19
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 358,
+ "width" : 13312,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 25
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 26
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 27
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 28
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 29
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 74,
+ "length" : 16,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 74,
+ "length" : 16,
+ "text" : "trigger a crash.",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 21,
+ "end" : 31,
+ "type" : "font-features",
+ "value" : "tnum=1"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 1058,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 91,
+ "length" : 26,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 91,
+ "length" : 26,
+ "text" : "If it doesn't the fix has ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 81,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 311,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 1099,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ },
+ {
+ "glyph" : 489,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 18
+ },
+ {
+ "glyph" : 472,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 20
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 21
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 22
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 23
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 24
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 25
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 117,
+ "length" : 7,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 117,
+ "length" : 7,
+ "text" : "worked.",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 467,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 345,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 280,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 1058,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 125,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-6.expected b/tests/layouts/valid-6.expected
deleted file mode 100644
index 040e0fa4..00000000
--- a/tests/layouts/valid-6.expected
+++ /dev/null
@@ -1,33 +0,0 @@
- 0️⃣ Keycap Digit Zero
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 25(1) 27(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr ' 0️⃣ Keycap Digit Zero
-'
-i=2, index=27, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' '
-i=2, index=1, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, '0️⃣'
-i=3, index=8, chars=18, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' Keycap Digit Zero'
-i=4, index=26, no run, line end
-i=5, index=27, no run, line end
diff --git a/tests/layouts/valid-6.layout b/tests/layouts/valid-6.layout
index 4423d068..d74ff4eb 100644
--- a/tests/layouts/valid-6.layout
+++ b/tests/layouts/valid-6.layout
@@ -1,5 +1,409 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : " 0️⃣ Keycap Digit Zero\n",
- "attributes" : [],
- "font" : "Cantarell 11"
+ "font" : "Cantarell 11",
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 1,
+ "width" : 151552,
+ "height" : 38912,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-start" : true,
+ "word-boundary" : true
+ },
+ { },
+ {
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 26,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 1,
+ "length" : 7,
+ "text" : "0️⃣",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 19,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 268443875,
+ "width" : 17408,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ },
+ {
+ "offset" : 8,
+ "length" : 18,
+ "text" : " Keycap Digit Zero",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 100,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 473,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 406,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 37,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 312,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 12
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ },
+ {
+ "glyph" : 239,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 14
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 15
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 16
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 17
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 27,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-7.expected b/tests/layouts/valid-7.expected
deleted file mode 100644
index 13595a75..00000000
--- a/tests/layouts/valid-7.expected
+++ /dev/null
@@ -1,43 +0,0 @@
-This is a test of the automatic emergency brake!
-
---- parameters
-
-wrapped: 0
-ellipsized: 1
-lines: 2
-width: 204800
-indent: 51200
-
---- attributes
-
-range 0 22
-range 22 41
-22 41 foreground #00000000ffff
-22 41 underline single
-range 41 2147483647
-
---- directions
-
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(0) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 47(1) 49(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'This is a test of the automatic emergency brake!
-'
-i=2, index=49, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=12, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'This is a te'
-i=2, index=12, chars=26, level=0, gravity=south, flags=2, font=OMITTED, script=common, language=en-us, 'st of the automatic emerge'
-0 2147483647 fallback false
-i=3, index=38, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'ncy'
-22 41 foreground #00000000ffff
-22 41 underline single
-i=4, index=41, chars=7, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, ' brake!'
-i=5, index=48, no run, line end
-i=6, index=49, no run, line end
diff --git a/tests/layouts/valid-7.layout b/tests/layouts/valid-7.layout
index b49484c6..705713ec 100644
--- a/tests/layouts/valid-7.layout
+++ b/tests/layouts/valid-7.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "This is a test of the automatic emergency brake!\n",
"attributes" : [
{
@@ -17,5 +33,612 @@
"font" : "Cantarell 11",
"ellipsize" : "middle",
"width" : 204800,
- "indent" : 51200
+ "indent" : 51200,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : true,
+ "unknown-glyphs" : 0,
+ "width" : 153600,
+ "height" : 37888,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 48,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 12,
+ "text" : "This is a te",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 187,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 319,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 417,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 7
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 430,
+ "width" : 5120,
+ "is-cluster-start" : true,
+ "log-cluster" : 10
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ }
+ ]
+ },
+ {
+ "offset" : 12,
+ "length" : 26,
+ "text" : "st of the automatic emerge",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "common",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 2,
+ "extra-attributes" : [
+ {
+ "end" : 2147483647,
+ "type" : "fallback",
+ "value" : false
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1062,
+ "width" : 16384,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 38,
+ "length" : 3,
+ "text" : "ncy",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "start" : 22,
+ "end" : 41,
+ "type" : "foreground",
+ "value" : "#00000000ffff"
+ },
+ {
+ "start" : 22,
+ "end" : 41,
+ "type" : "underline",
+ "value" : "single"
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 360,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 273,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 473,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ }
+ ]
+ },
+ {
+ "offset" : 41,
+ "length" : 7,
+ "text" : " brake!",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 272,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 409,
+ "width" : 6144,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 244,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 345,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ },
+ {
+ "glyph" : 1063,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 49,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-8.expected b/tests/layouts/valid-8.expected
deleted file mode 100644
index 185ba373..00000000
--- a/tests/layouts/valid-8.expected
+++ /dev/null
@@ -1,34 +0,0 @@
-Hello שלום Γειά σας
-
---- parameters
-
-wrapped: 0
-ellipsized: 0
-lines: 2
-
---- attributes
-
-range 0 2147483647
-
---- directions
-
-0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 6(0) 12(0) 10(0) 8(0) 14(0) 15(0) 17(0) 19(0) 21(0) 23(0) 24(0) 26(0) 28(0) 28(1) 31(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'Hello שלום Γειά σας
-'
-i=2, index=31, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=6, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Hello '
-i=2, index=12, chars=4, level=1, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, 'שלום'
-i=3, index=14, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, ' '
-i=4, index=15, chars=8, level=0, gravity=south, flags=0, font=OMITTED, script=greek, language=el, 'Γειά σας'
-i=5, index=30, no run, line end
-i=6, index=31, no run, line end
diff --git a/tests/layouts/valid-8.layout b/tests/layouts/valid-8.layout
index 063ec370..ef463535 100644
--- a/tests/layouts/valid-8.layout
+++ b/tests/layouts/valid-8.layout
@@ -1,8 +1,416 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "Hello שלום Γειά σας\n",
- "attributes" : [],
"font" : "Cantarell 11",
"auto-dir" : false,
"alignment" : "center",
- "spacing" : 51200
+ "spacing" : 51200,
+ "output" : {
+ "is-wrapped" : false,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 134144,
+ "height" : 90112,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "backspace-deletes-character" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 30,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 6,
+ "text" : "Hello ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 76,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 349,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 370,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ }
+ ]
+ },
+ {
+ "offset" : 6,
+ "length" : 8,
+ "text" : "שלום",
+ "bidi-level" : 1,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1332,
+ "width" : 10240,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1324,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1331,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1344,
+ "width" : 11264,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 14,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 15,
+ "length" : 15,
+ "text" : "Γειά σας",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "el",
+ "script" : "greek",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 677,
+ "width" : 8192,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 808,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 812,
+ "width" : 4096,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 837,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1109,
+ "width" : 3072,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ },
+ {
+ "glyph" : 822,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 9
+ },
+ {
+ "glyph" : 804,
+ "width" : 9216,
+ "is-cluster-start" : true,
+ "log-cluster" : 11
+ },
+ {
+ "glyph" : 821,
+ "width" : 7168,
+ "is-cluster-start" : true,
+ "log-cluster" : 13
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 31,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/layouts/valid-9.expected b/tests/layouts/valid-9.expected
deleted file mode 100644
index 5cbbf8fc..00000000
--- a/tests/layouts/valid-9.expected
+++ /dev/null
@@ -1,49 +0,0 @@
-Hello שלום Γειά σας
-
---- parameters
-
-wrapped: 1
-ellipsized: 0
-lines: 5
-width: 102400
-
---- attributes
-
-range 0 30
-0 30 letter-spacing 8888
-range 30 2147483647
-
---- directions
-
-0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0
-
---- cursor positions
-
-0(0) 1(0) 2(0) 3(0) 4(0) 5(0) 5(1) 12(0) 10(0) 8(0) 14(0) 14(1) 17(0) 19(0) 21(0) 23(0) 23(1) 26(0) 28(0) 28(1) 31(0)
-
---- lines
-
-i=1, index=0, paragraph-start=1, dir=ltr 'Hello שלו'
-i=2, index=12, paragraph-start=0, dir=ltr 'ם '
-i=3, index=15, paragraph-start=0, dir=ltr 'Γειά '
-i=4, index=24, paragraph-start=0, dir=ltr 'σας
-'
-i=5, index=31, paragraph-start=1, dir=ltr ''
-
---- runs
-
-i=1, index=0, chars=6, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'Hello '
-0 30 letter-spacing 8888
-i=2, index=6, no run, line end
-i=3, index=12, chars=4, level=1, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, 'שלום'
-0 30 letter-spacing 8888
-i=4, index=14, chars=1, level=0, gravity=south, flags=0, font=OMITTED, script=hebrew, language=he, ' '
-0 30 letter-spacing 8888
-i=5, index=15, no run, line end
-i=6, index=15, chars=5, level=0, gravity=south, flags=0, font=OMITTED, script=greek, language=el, 'Γειά '
-0 30 letter-spacing 8888
-i=7, index=24, no run, line end
-i=8, index=24, chars=3, level=0, gravity=south, flags=0, font=OMITTED, script=greek, language=el, 'σας'
-0 30 letter-spacing 8888
-i=9, index=30, no run, line end
-i=10, index=31, no run, line end
diff --git a/tests/layouts/valid-9.layout b/tests/layouts/valid-9.layout
index e3dfa57b..20cf4e84 100644
--- a/tests/layouts/valid-9.layout
+++ b/tests/layouts/valid-9.layout
@@ -1,4 +1,20 @@
{
+ "context" : {
+ "font" : "serif 12",
+ "language" : "en-us",
+ "base-gravity" : "south",
+ "gravity-hint" : "natural",
+ "base-dir" : "weak-ltr",
+ "round-glyph-positions" : true,
+ "transform" : [
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
"text" : "Hello שלום Γειά σας\n",
"attributes" : [
{
@@ -8,5 +24,502 @@
}
],
"font" : "Cantarell 11",
- "width" : 102400
+ "width" : 102400,
+ "output" : {
+ "is-wrapped" : true,
+ "is-ellipsized" : false,
+ "unknown-glyphs" : 0,
+ "width" : 71392,
+ "height" : 94208,
+ "log-attrs" : [
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "sentence-boundary" : true,
+ "sentence-start" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "backspace-deletes-character" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "backspace-deletes-character" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "expandable-space" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "char-break" : true,
+ "cursor-position" : true,
+ "word-start" : true,
+ "word-boundary" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "cursor-position" : true,
+ "break-inserts-hyphen" : true
+ },
+ {
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "word-end" : true,
+ "sentence-end" : true,
+ "word-boundary" : true
+ },
+ {
+ "line-break" : true,
+ "mandatory-break" : true,
+ "char-break" : true,
+ "white" : true,
+ "cursor-position" : true,
+ "sentence-boundary" : true,
+ "backspace-deletes-character" : true,
+ "word-boundary" : true
+ }
+ ],
+ "lines" : [
+ {
+ "start-index" : 0,
+ "length" : 6,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 0,
+ "length" : 6,
+ "text" : "Hello ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "en-us",
+ "script" : "latin",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 30,
+ "type" : "letter-spacing",
+ "value" : 8888
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 76,
+ "width" : 15708,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 287,
+ "width" : 17080,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 1
+ },
+ {
+ "glyph" : 349,
+ "width" : 12984,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 349,
+ "width" : 12984,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 3
+ },
+ {
+ "glyph" : 370,
+ "width" : 12636,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 5
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 6,
+ "length" : 9,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 6,
+ "length" : 8,
+ "text" : "שלום",
+ "bidi-level" : 1,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "DejaVu Sans 11",
+ "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01",
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 30,
+ "type" : "letter-spacing",
+ "value" : 8888
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 1332,
+ "width" : 14684,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 1324,
+ "width" : 12984,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 1331,
+ "width" : 18104,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 1344,
+ "width" : 20152,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ },
+ {
+ "offset" : 14,
+ "length" : 1,
+ "text" : " ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "he",
+ "script" : "hebrew",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 30,
+ "type" : "letter-spacing",
+ "value" : 8888
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 15,
+ "length" : 9,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 15,
+ "length" : 9,
+ "text" : "Γειά ",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "el",
+ "script" : "greek",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 30,
+ "type" : "letter-spacing",
+ "value" : 8888
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 677,
+ "width" : 12636,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 808,
+ "width" : 16056,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 812,
+ "width" : 12984,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ },
+ {
+ "glyph" : 837,
+ "width" : 13660,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 6
+ },
+ {
+ "glyph" : 268435455,
+ "width" : 0,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 8
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 24,
+ "length" : 6,
+ "paragraph-start" : false,
+ "direction" : "ltr",
+ "runs" : [
+ {
+ "offset" : 24,
+ "length" : 6,
+ "text" : "σας",
+ "bidi-level" : 0,
+ "gravity" : "south",
+ "language" : "el",
+ "script" : "greek",
+ "font" : {
+ "description" : "Cantarell 11",
+ "checksum" : "5bcb6ee14ee9d210b2e91d643de1fe456e9d1aea770983fdb05951545efebbe2",
+ "variations" : {
+ "wght" : 0
+ },
+ "matrix" : [
+ 1.0,
+ -0.0,
+ -0.0,
+ 1.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "flags" : 0,
+ "extra-attributes" : [
+ {
+ "end" : 30,
+ "type" : "letter-spacing",
+ "value" : 8888
+ }
+ ],
+ "y-offset" : 0,
+ "start-x-offset" : 0,
+ "end-x-offset" : 0,
+ "glyphs" : [
+ {
+ "glyph" : 822,
+ "width" : 13660,
+ "is-cluster-start" : true,
+ "log-cluster" : 0
+ },
+ {
+ "glyph" : 804,
+ "width" : 18104,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 2
+ },
+ {
+ "glyph" : 821,
+ "width" : 11612,
+ "x-offset" : 4444,
+ "is-cluster-start" : true,
+ "log-cluster" : 4
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "start-index" : 31,
+ "length" : 0,
+ "paragraph-start" : true,
+ "direction" : "ltr",
+ "runs" : []
+ }
+ ]
+ }
}
diff --git a/tests/meson.build b/tests/meson.build
index 00741a14..1984ed03 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -44,18 +44,28 @@ if cairo_dep.found()
[ 'testiter', [ 'testiter.c' ], [ libpangocairo_dep ] ],
[ 'test-ellipsize', [ 'test-ellipsize.c' ], [ libpangocairo_dep ] ],
[ 'markup-parse', [ 'markup-parse.c' , 'test-common.c' ], [ libpangocairo_dep ] ],
- [ 'test-layout', [ 'test-layout.c', 'test-common.c' ], [ libpangocairo_dep ] ],
[ 'test-itemize', [ 'test-itemize.c', 'test-common.c' ], [ libpangocairo_dep ] ],
[ 'test-shape', [ 'test-shape.c', 'test-common.c' ], [ libpangocairo_dep ] ],
[ 'test-font', [ 'test-font.c' ], [ libpangocairo_dep ] ],
[ 'testattributes', [ 'testattributes.c', 'test-common.c' ], [ libpangocairo_dep ] ],
- [ 'testmisc', [ 'testmisc.c' ], [ libpangocairo_dep, libpangoft2_dep, glib_dep, harfbuzz_dep ] ],
[ 'cxx-test', [ 'cxx-test.cpp' ], [ libpangocairo_dep, gobject_dep, harfbuzz_dep ] ],
[ 'test-harfbuzz', [ 'test-harfbuzz.c' ], [ libpangocairo_dep, gobject_dep, harfbuzz_dep ] ],
[ 'test-break', [ 'test-break.c', 'test-common.c', 'validate-log-attrs.c' ], [libpangocairo_dep, glib_dep, harfbuzz_dep ] ],
[ 'testserialize', [ 'testserialize.c' ], [ libpangocairo_dep ] ],
]
+ if build_pangoft2
+ tests += [
+ [ 'testmisc', [ 'testmisc.c' ], [ libpangocairo_dep, libpangoft2_dep, glib_dep, harfbuzz_dep ] ],
+ ]
+
+ if host_system != 'darwin'
+ tests += [
+ [ 'test-layout', [ 'test-layout.c', 'test-common.c' ], [ libpangocairo_dep, libpangoft2_dep ] ],
+ ]
+ endif
+ endif
+
if host_system != 'darwin'
tests += [
[ 'testrandom', [ 'testrandom.c' ], [ libpangocairo_dep, gio_dep ] ],
diff --git a/tests/test-common.c b/tests/test-common.c
index 3821a450..12b22cb4 100644
--- a/tests/test-common.c
+++ b/tests/test-common.c
@@ -82,6 +82,70 @@ done:
return diff;
}
+char *
+diff_bytes (GBytes *b1,
+ GBytes *b2,
+ GError **error)
+{
+ const char *command[] = { "diff", "-u", "-i", NULL, NULL, NULL };
+ char *diff, *tmpfile, *tmpfile2;
+ int fd;
+ const char *text;
+ gsize len;
+
+ /* write the text buffer to a temporary file */
+ fd = g_file_open_tmp (NULL, &tmpfile, error);
+ if (fd < 0)
+ return NULL;
+
+ text = (const char *) g_bytes_get_data (b1, &len);
+ if (write (fd, text, len) != (int) len)
+ {
+ close (fd);
+ g_set_error (error,
+ G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ "Could not write data to temporary file '%s'", tmpfile);
+ goto done;
+ }
+ close (fd);
+
+ fd = g_file_open_tmp (NULL, &tmpfile2, error);
+ if (fd < 0)
+ return NULL;
+
+ text = (const char *) g_bytes_get_data (b2, &len);
+ if (write (fd, text, len) != (int) len)
+ {
+ close (fd);
+ g_set_error (error,
+ G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ "Could not write data to temporary file '%s'", tmpfile2);
+ goto done;
+ }
+ close (fd);
+
+ command[3] = tmpfile;
+ command[4] = tmpfile2;
+
+ /* run diff command */
+ g_spawn_sync (NULL,
+ (char **) command,
+ NULL,
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL,
+ &diff,
+ NULL, NULL,
+ error);
+
+done:
+ unlink (tmpfile);
+ g_free (tmpfile);
+ unlink (tmpfile2);
+ g_free (tmpfile2);
+
+ return diff;
+}
+
gboolean
file_has_prefix (const char *filename,
const char *str,
diff --git a/tests/test-common.h b/tests/test-common.h
index 86320236..6fe96133 100644
--- a/tests/test-common.h
+++ b/tests/test-common.h
@@ -6,6 +6,10 @@ char * diff_with_file (const char *file,
gssize len,
GError **error);
+char * diff_bytes (GBytes *b1,
+ GBytes *b2,
+ GError **error);
+
gboolean file_has_prefix (const char *file,
const char *str,
GError **error);
diff --git a/tests/test-layout.c b/tests/test-layout.c
index 7415efe7..62aba460 100644
--- a/tests/test-layout.c
+++ b/tests/test-layout.c
@@ -29,278 +29,29 @@
#include "config.h"
#include <pango/pangocairo.h>
+#include <pango/pangocairo-fc.h>
+#include <pango/pangofc-fontmap.h>
#include "test-common.h"
-static PangoContext *context;
-
-static gboolean opt_show_font;
-
-static const gchar *
-enum_value_nick (GType type, gint value)
-{
- GEnumClass *eclass;
- GEnumValue *ev;
-
- eclass = g_type_class_ref (type);
- ev = g_enum_get_value (eclass, value);
- g_type_class_unref (eclass);
-
- if (ev)
- return ev->value_nick;
- else
- return "?";
-}
-
-static const gchar *
-direction_name (PangoDirection dir)
-{
- return enum_value_nick (PANGO_TYPE_DIRECTION, dir);
-}
-
-static const gchar *
-gravity_name (PangoGravity gravity)
-{
- return enum_value_nick (PANGO_TYPE_GRAVITY, gravity);
-}
-
-static const gchar *
-script_name (PangoScript script)
-{
- return enum_value_nick (PANGO_TYPE_SCRIPT, script);
-}
-
-static gchar *
-font_name (PangoFont *font)
-{
- PangoFontDescription *desc;
- gchar *name;
-
- desc = pango_font_describe (font);
- name = pango_font_description_to_string (desc);
- pango_font_description_free (desc);
-
- return name;
-}
-
-static void
-dump_lines (PangoLayout *layout, GString *string)
-{
- PangoLayoutIter *iter;
- const gchar *text;
- gint index, index2;
- gboolean has_more;
- gchar *char_str;
- gint i;
- PangoLayoutLine *line;
-
- text = pango_layout_get_text (layout);
- iter = pango_layout_get_iter (layout);
-
- has_more = TRUE;
- index = pango_layout_iter_get_index (iter);
- index2 = 0;
- i = 0;
- while (has_more)
- {
- line = pango_layout_iter_get_line (iter);
- has_more = pango_layout_iter_next_line (iter);
- i++;
-
- if (has_more)
- {
- index2 = pango_layout_iter_get_index (iter);
- char_str = g_strndup (text + index, index2 - index);
- }
- else
- {
- char_str = g_strdup (text + index);
- }
-
- g_string_append_printf (string, "i=%d, index=%d, paragraph-start=%d, dir=%s '%s'\n",
- i, index, line->is_paragraph_start, direction_name (line->resolved_dir),
- char_str);
- g_free (char_str);
-
- index = index2;
- }
- pango_layout_iter_free (iter);
-}
-
-#define ANALYSIS_FLAGS (PANGO_ANALYSIS_FLAG_CENTERED_BASELINE | \
- PANGO_ANALYSIS_FLAG_IS_ELLIPSIS | \
- PANGO_ANALYSIS_FLAG_NEED_HYPHEN)
-
-static void
-dump_runs (PangoLayout *layout, GString *string)
-{
- PangoLayoutIter *iter;
- PangoLayoutRun *run;
- PangoItem *item;
- const gchar *text;
- gint index;
- gboolean has_more;
- gchar *char_str;
- gint i;
- gchar *font = 0;
-
- text = pango_layout_get_text (layout);
- iter = pango_layout_get_iter (layout);
-
- has_more = TRUE;
- i = 0;
- while (has_more)
- {
- run = pango_layout_iter_get_run (iter);
- index = pango_layout_iter_get_index (iter);
- has_more = pango_layout_iter_next_run (iter);
- i++;
-
- if (run)
- {
- item = ((PangoGlyphItem*)run)->item;
- char_str = g_strndup (text + item->offset, item->length);
- font = font_name (item->analysis.font);
- g_string_append_printf (string, "i=%d, index=%d, chars=%d, level=%d, gravity=%s, flags=%d, font=%s, script=%s, language=%s, '%s'\n",
- i, index, item->num_chars, item->analysis.level,
- gravity_name (item->analysis.gravity),
- item->analysis.flags & ANALYSIS_FLAGS,
- opt_show_font ? font : "OMITTED", /* for some reason, this fails on build.gnome.org, so leave it out */
- script_name (item->analysis.script),
- pango_language_to_string (item->analysis.language),
- char_str);
- print_attributes (item->analysis.extra_attrs, string);
- g_free (font);
- g_free (char_str);
- }
- else
- {
- g_string_append_printf (string, "i=%d, index=%d, no run, line end\n",
- i, index);
- }
- }
- pango_layout_iter_free (iter);
-}
-
-static void
-dump_directions (PangoLayout *layout, GString *string)
-{
- const char *text, *p;
-
- text = pango_layout_get_text (layout);
- for (p = text; *p; p = g_utf8_next_char (p))
- {
- g_string_append_printf (string, "%d ", pango_layout_get_direction (layout, p - text));
- }
- g_string_append (string, "\n");
-}
-
-static void
-dump_cursor_positions (PangoLayout *layout, GString *string)
-{
- const char *text;
- int index, trailing;
-
- text = pango_layout_get_text (layout);
-
- index = 0;
- trailing = 0;
-
- while (index < G_MAXINT)
- {
- g_string_append_printf (string, "%d(%d) ", index, trailing);
-
- while (trailing--)
- index = g_utf8_next_char (text + index) - text;
-
- pango_layout_move_cursor_visually (layout, TRUE, index, 0, 1, &index, &trailing);
- }
-
- g_string_append (string, "\n");
-}
-
-static void
-test_file (const char *filename, GString *string)
-{
- char *contents;
- gsize length;
- GBytes *bytes;
- GError *error = NULL;
- PangoLayout *layout;
-
- if (context == NULL)
- context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
-
- g_file_get_contents (filename, &contents, &length, &error);
- g_assert_no_error (error);
-
- bytes = g_bytes_new_take (contents, length);
-
- layout = pango_layout_deserialize (context, bytes, &error);
- g_assert_no_error (error);
-
- g_bytes_unref (bytes);
-
- /* generate the dumps */
- g_string_append (string, pango_layout_get_text (layout));
-
- g_string_append (string, "\n--- parameters\n\n");
-
- g_string_append_printf (string, "wrapped: %d\n", pango_layout_is_wrapped (layout));
- g_string_append_printf (string, "ellipsized: %d\n", pango_layout_is_ellipsized (layout));
- g_string_append_printf (string, "lines: %d\n", pango_layout_get_line_count (layout));
- if (pango_layout_get_width (layout) > 0)
- g_string_append_printf (string, "width: %d\n", pango_layout_get_width (layout));
- if (pango_layout_get_height (layout) > 0)
- g_string_append_printf (string, "height: %d\n", pango_layout_get_height (layout));
- if (pango_layout_get_indent (layout) != 0)
- g_string_append_printf (string, "indent: %d\n", pango_layout_get_indent (layout));
-
- g_string_append (string, "\n--- attributes\n\n");
- print_attr_list (pango_layout_get_attributes (layout), string);
-
- g_string_append (string, "\n--- directions\n\n");
- dump_directions (layout, string);
-
- g_string_append (string, "\n--- cursor positions\n\n");
- dump_cursor_positions (layout, string);
-
- g_string_append (string, "\n--- lines\n\n");
- dump_lines (layout, string);
-
- g_string_append (string, "\n--- runs\n\n");
- dump_runs (layout, string);
-
- g_object_unref (layout);
-}
-
-static gchar *
-get_expected_filename (const char *filename)
-{
- char *f, *p, *expected;
-
- f = g_strdup (filename);
- p = strstr (f, ".layout");
- if (p)
- *p = 0;
- expected = g_strconcat (f, ".expected", NULL);
-
- g_free (f);
-
- return expected;
-}
-
static void
test_layout (gconstpointer d)
{
const char *filename = d;
- char *expected_file;
GError *error = NULL;
- GString *dump;
char *diff;
- PangoFontFamily **families;
- int n_families;
- gboolean found_cantarell;
+ GBytes *bytes;
+ char *contents;
+ gsize length;
+ GBytes *orig;
+ PangoContext *context;
+ PangoLayout *layout;
+
+ if (!PANGO_IS_FC_FONT_MAP (pango_cairo_font_map_get_default ()))
+ {
+ g_test_skip ("Not an fc fontmap. Skipping...");
+ return;
+ }
char *old_locale = g_strdup (setlocale (LC_ALL, NULL));
setlocale (LC_ALL, "en_US.UTF-8");
@@ -313,39 +64,25 @@ test_layout (gconstpointer d)
return;
}
- if (context == NULL)
- context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
-
- found_cantarell = FALSE;
- pango_context_list_families (context, &families, &n_families);
- for (int i = 0; i < n_families; i++)
- {
- if (strcmp (pango_font_family_get_name (families[i]), "Cantarell") == 0)
- {
- found_cantarell = TRUE;
- break;
- }
- }
- g_free (families);
-
- if (!found_cantarell)
- {
- char *msg = g_strdup_printf ("Cantarell font not available, skipping itemization %s", filename);
- g_test_skip (msg);
- g_free (msg);
- g_free (old_locale);
- return;
- }
+ g_file_get_contents (filename, &contents, &length, &error);
+ g_assert_no_error (error);
+ orig = g_bytes_new_take (contents, length);
- expected_file = get_expected_filename (filename);
+ context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
+ layout = pango_layout_deserialize (context, orig, PANGO_LAYOUT_DESERIALIZE_CONTEXT, &error);
+ g_assert_no_error (error);
- dump = g_string_sized_new (0);
+ bytes = pango_layout_serialize (layout, PANGO_LAYOUT_SERIALIZE_CONTEXT | PANGO_LAYOUT_SERIALIZE_OUTPUT);
- test_file (filename, dump);
+ g_object_unref (layout);
+ g_object_unref (context);
- diff = diff_with_file (expected_file, dump->str, dump->len, &error);
+ diff = diff_bytes (orig, bytes, &error);
g_assert_no_error (error);
+ g_bytes_unref (bytes);
+ g_bytes_unref (orig);
+
setlocale (LC_ALL, old_locale);
g_free (old_locale);
@@ -365,8 +102,37 @@ test_layout (gconstpointer d)
}
g_free (diff);
- g_string_free (dump, TRUE);
- g_free (expected_file);
+}
+
+static void
+install_fonts (const char *dir)
+{
+ FcConfig *config;
+ PangoFontMap *map;
+ char *conf;
+
+ map = g_object_new (PANGO_TYPE_CAIRO_FC_FONT_MAP, NULL);
+
+ config = FcConfigCreate ();
+
+ conf = g_strdup_printf ("<?xml version=\"1.0\"?>\n"
+ "<!DOCTYPE fontconfig SYSTEM \"urn:fontconfig:fonts.dtd\">\n"
+ "<fontconfig>\n"
+ " <cachedir>%s/cache</cachedir>\n"
+ "</fontconfig>", dir);
+
+ if (!FcConfigParseAndLoadFromMemory (config, (const FcChar8 *) conf, TRUE))
+ g_error ("Failed to parse fontconfig configuration");
+
+ g_free (conf);
+
+ FcConfigAppFontAddDir (config, (const FcChar8 *) dir);
+ pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (map), config);
+ FcConfigDestroy (config);
+
+ pango_cairo_font_map_set_default (PANGO_CAIRO_FONT_MAP (map));
+
+ g_object_unref (map);
}
int
@@ -374,11 +140,12 @@ main (int argc, char *argv[])
{
GDir *dir;
GError *error = NULL;
+ char *opt_fonts = NULL;
const gchar *name;
char *path;
GOptionContext *option_context;
GOptionEntry entries[] = {
- { "show-fonts", '0', 0, G_OPTION_ARG_NONE, &opt_show_font, "Print font names in dumps", NULL },
+ { "fonts", 0, 0, G_OPTION_ARG_FILENAME, &opt_fonts, "Fonts to use", "DIR" },
{ NULL, 0 },
};
@@ -394,24 +161,49 @@ main (int argc, char *argv[])
}
g_option_context_free (option_context);
- if (g_getenv ("PANGO_TEST_SHOW_FONT"))
- opt_show_font = TRUE;
+ if (opt_fonts)
+ install_fonts (opt_fonts);
/* allow to easily generate expected output for new test cases */
if (argc > 1 && argv[1][0] != '-')
{
- GString *string;
+ char *contents;
+ gsize length;
+ GError *error = NULL;
+ GBytes *orig;
+ GBytes *bytes;
+ PangoContext *context;
+ PangoLayout *layout;
- string = g_string_sized_new (0);
- test_file (argv[1], string);
- g_print ("%s", string->str);
- g_string_free (string, TRUE);
+ g_file_get_contents (argv[1], &contents, &length, &error);
+ g_assert_no_error (error);
+ orig = g_bytes_new_take (contents, length);
+ context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
+ layout = pango_layout_deserialize (context, orig, PANGO_LAYOUT_DESERIALIZE_CONTEXT, &error);
+ g_assert_no_error (error);
+
+ bytes = pango_layout_serialize (layout, PANGO_LAYOUT_SERIALIZE_CONTEXT | PANGO_LAYOUT_SERIALIZE_OUTPUT);
+
+ g_object_unref (layout);
+ g_object_unref (context);
+
+ g_print ("%s", (const char *)g_bytes_get_data (bytes, NULL));
+
+ g_bytes_unref (bytes);
+ g_bytes_unref (orig);
return 0;
}
g_test_init (&argc, &argv, NULL);
+ if (!opt_fonts)
+ {
+ path = g_test_build_filename (G_TEST_DIST, "fonts", NULL);
+ install_fonts (path);
+ g_free (path);
+ }
+
path = g_test_build_filename (G_TEST_DIST, "layouts", NULL);
dir = g_dir_open (path, 0, &error);
g_free (path);
diff --git a/tests/testserialize.c b/tests/testserialize.c
index 5fb7543a..bd962a56 100644
--- a/tests/testserialize.c
+++ b/tests/testserialize.c
@@ -19,6 +19,7 @@
*/
#include "config.h"
+
#include <glib.h>
#include <pango/pangocairo.h>
#include <gio/gio.h>
@@ -129,7 +130,7 @@ test_serialize_layout_minimal (void)
const char *test =
"{\n"
" \"text\" : \"Almost nothing\"\n"
- "}";
+ "}\n";
PangoContext *context;
GBytes *bytes;
@@ -142,7 +143,7 @@ test_serialize_layout_minimal (void)
bytes = g_bytes_new_static (test, -1);
- layout = pango_layout_deserialize (context, bytes, &error);
+ layout = pango_layout_deserialize (context, bytes, PANGO_LAYOUT_DESERIALIZE_DEFAULT, &error);
g_assert_no_error (error);
g_assert_true (PANGO_IS_LAYOUT (layout));
g_assert_cmpstr (pango_layout_get_text (layout), ==, "Almost nothing");
@@ -152,7 +153,7 @@ test_serialize_layout_minimal (void)
g_assert_cmpint (pango_layout_get_alignment (layout), ==, PANGO_ALIGN_LEFT);
g_assert_cmpint (pango_layout_get_width (layout), ==, -1);
- out_bytes = pango_layout_serialize (layout);
+ out_bytes = pango_layout_serialize (layout, PANGO_LAYOUT_SERIALIZE_DEFAULT);
str = g_bytes_get_data (out_bytes, NULL);
g_assert_cmpstr (str, ==, test);
@@ -200,7 +201,7 @@ test_serialize_layout_valid (void)
" \"alignment\" : \"center\",\n"
" \"width\" : 350000,\n"
" \"line-spacing\" : 1.5\n"
- "}";
+ "}\n";
PangoContext *context;
GBytes *bytes;
@@ -208,14 +209,13 @@ test_serialize_layout_valid (void)
PangoTabArray *tabs;
GError *error = NULL;
GBytes *out_bytes;
- const char *str;
char *s;
context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
bytes = g_bytes_new_static (test, -1);
- layout = pango_layout_deserialize (context, bytes, &error);
+ layout = pango_layout_deserialize (context, bytes, PANGO_LAYOUT_DESERIALIZE_DEFAULT, &error);
g_assert_no_error (error);
g_assert_true (PANGO_IS_LAYOUT (layout));
g_assert_cmpstr (pango_layout_get_text (layout), ==, "Some fun with layouts!");
@@ -230,12 +230,47 @@ test_serialize_layout_valid (void)
g_assert_cmpint (pango_layout_get_width (layout), ==, 350000);
g_assert_cmpfloat_with_epsilon (pango_layout_get_line_spacing (layout), 1.5, 0.0001);
- out_bytes = pango_layout_serialize (layout);
- str = g_bytes_get_data (out_bytes, NULL);
+ out_bytes = pango_layout_serialize (layout, PANGO_LAYOUT_SERIALIZE_DEFAULT);
- g_assert_cmpstr (str, ==, test);
+ g_assert_cmpstr (g_bytes_get_data (out_bytes, NULL), ==, g_bytes_get_data (bytes, NULL));
g_bytes_unref (out_bytes);
+ g_bytes_unref (bytes);
+
+ g_object_unref (layout);
+ g_object_unref (context);
+}
+
+static void
+test_serialize_layout_context (void)
+{
+ const char *test =
+ "{\n"
+ " \"context\" : {\n"
+ " \"base-gravity\" : \"east\",\n"
+ " \"language\" : \"de-de\",\n"
+ " \"round-glyph-positions\" : \"false\"\n"
+ " },\n"
+ " \"text\" : \"Some fun with layouts!\"\n"
+ "}\n";
+
+ PangoContext *context;
+ GBytes *bytes;
+ PangoLayout *layout;
+ GError *error = NULL;
+
+ context = pango_font_map_create_context (pango_cairo_font_map_get_default ());
+
+ bytes = g_bytes_new_static (test, -1);
+
+ layout = pango_layout_deserialize (context, bytes, PANGO_LAYOUT_DESERIALIZE_CONTEXT, &error);
+ g_assert_no_error (error);
+ g_assert_true (PANGO_IS_LAYOUT (layout));
+ g_assert_cmpstr (pango_layout_get_text (layout), ==, "Some fun with layouts!");
+
+ g_assert_cmpint (pango_context_get_base_gravity (context), ==, PANGO_GRAVITY_EAST);
+ g_assert_true (pango_context_get_language (context) == pango_language_from_string ("de-de"));
+ g_assert_false (pango_context_get_round_glyph_positions (context));
g_object_unref (layout);
g_bytes_unref (bytes);
@@ -256,8 +291,8 @@ test_serialize_layout_invalid (void)
" \"type\" : \"caramba\"\n"
" }\n"
" ]\n"
- "}",
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE
+ "}\n",
+ PANGO_LAYOUT_DESERIALIZE_INVALID_VALUE
},
{
"{\n"
@@ -266,8 +301,8 @@ test_serialize_layout_invalid (void)
" \"type\" : \"weight\"\n"
" }\n"
" ]\n"
- "}",
- PANGO_LAYOUT_SERIALIZE_MISSING_VALUE
+ "}\n",
+ PANGO_LAYOUT_DESERIALIZE_MISSING_VALUE
},
{
"{\n"
@@ -277,14 +312,22 @@ test_serialize_layout_invalid (void)
" \"value\" : \"nonsense\"\n"
" }\n"
" ]\n"
- "}",
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE
+ "}\n",
+ PANGO_LAYOUT_DESERIALIZE_INVALID_VALUE
},
{
"{\n"
" \"alignment\" : \"nonsense\"\n"
- "}",
- PANGO_LAYOUT_SERIALIZE_INVALID_VALUE
+ "}\n",
+ PANGO_LAYOUT_DESERIALIZE_INVALID_VALUE
+ },
+ {
+ "{\n"
+ " \"attributes\" : {\n"
+ " \"name\" : \"This is wrong\"\n"
+ " }\n"
+ "}\n",
+ PANGO_LAYOUT_DESERIALIZE_INVALID_SYNTAX
}
};
@@ -299,9 +342,9 @@ test_serialize_layout_invalid (void)
GError *error = NULL;
bytes = g_bytes_new_static (test[i].json, -1);
- layout = pango_layout_deserialize (context, bytes, &error);
+ layout = pango_layout_deserialize (context, bytes, PANGO_LAYOUT_DESERIALIZE_DEFAULT, &error);
g_assert_null (layout);
- g_assert_error (error, PANGO_LAYOUT_SERIALIZE_ERROR, test[i].expected_error);
+ g_assert_error (error, PANGO_LAYOUT_DESERIALIZE_ERROR, test[i].expected_error);
g_bytes_unref (bytes);
g_clear_error (&error);
}
@@ -317,6 +360,7 @@ main (int argc, char *argv[])
g_test_add_func ("/serialize/tab-array", test_serialize_tab_array);
g_test_add_func ("/serialize/layout/minimal", test_serialize_layout_minimal);
g_test_add_func ("/serialize/layout/valid", test_serialize_layout_valid);
+ g_test_add_func ("/serialize/layout/context", test_serialize_layout_context);
g_test_add_func ("/serialize/layout/invalid", test_serialize_layout_invalid);
return g_test_run ();
diff --git a/utils/viewer-render.c b/utils/viewer-render.c
index 23e13c71..3217d80f 100644
--- a/utils/viewer-render.c
+++ b/utils/viewer-render.c
@@ -115,7 +115,7 @@ make_layout(PangoContext *context,
if (!g_file_get_contents (file_arg, &text, &len, &error))
fail ("%s\n", error->message);
bytes = g_bytes_new_take (text, size);
- layout = pango_layout_deserialize (context, bytes, &error);
+ layout = pango_layout_deserialize (context, bytes, PANGO_LAYOUT_DESERIALIZE_CONTEXT, &error);
if (!layout)
fail ("%s\n", error->message);
g_bytes_unref (bytes);