diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/test-repacker.cc')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/test-repacker.cc | 1041 |
1 files changed, 958 insertions, 83 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/test-repacker.cc b/src/3rdparty/harfbuzz-ng/src/test-repacker.cc index 6f46b04287..3a2536a29a 100644 --- a/src/3rdparty/harfbuzz-ng/src/test-repacker.cc +++ b/src/3rdparty/harfbuzz-ng/src/test-repacker.cc @@ -56,6 +56,51 @@ static void add_offset (unsigned id, c->add_link (*offset, id); } +static void add_wide_offset (unsigned id, + hb_serialize_context_t* c) +{ + OT::Offset32* offset = c->start_embed<OT::Offset32> (); + c->extend_min (offset); + c->add_link (*offset, id); +} + +static void run_resolve_overflow_test (const char* name, + hb_serialize_context_t& overflowing, + hb_serialize_context_t& expected, + unsigned num_iterations = 0) +{ + printf (">>> Testing overflowing resolution for %s\n", + name); + + graph_t graph (overflowing.object_graph ()); + + + assert (overflowing.offset_overflow ()); + hb_blob_t* out = hb_resolve_overflows (overflowing.object_graph (), + HB_TAG ('G', 'S', 'U', 'B'), num_iterations); + assert (out); + + hb_bytes_t result = out->as_bytes (); + + assert (!expected.offset_overflow ()); + hb_bytes_t expected_result = expected.copy_bytes (); + + assert (result.length == expected_result.length); + for (unsigned i = 0; i < expected_result.length; i++) + { + assert (result[i] == expected_result[i]); + } + + expected_result.fini (); + hb_blob_destroy (out); +} + +static void add_virtual_offset (unsigned id, + hb_serialize_context_t* c) +{ + c->add_virtual_link (id); +} + static void populate_serializer_simple (hb_serialize_context_t* c) { @@ -67,7 +112,7 @@ populate_serializer_simple (hb_serialize_context_t* c) start_object ("abc", 3, c); add_offset (obj_2, c); add_offset (obj_1, c); - c->pop_pack (); + c->pop_pack (false); c->end_serialize(); } @@ -86,12 +131,64 @@ populate_serializer_with_overflow (hb_serialize_context_t* c) add_offset (obj_3, c); add_offset (obj_2, c); add_offset (obj_1, c); - c->pop_pack (); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_priority_overflow (hb_serialize_context_t* c) +{ + std::string large_string(50000, 'a'); + c->start_serialize<char> (); + + unsigned obj_e = add_object ("e", 1, c); + unsigned obj_d = add_object ("d", 1, c); + + start_object (large_string.c_str (), 50000, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object (large_string.c_str (), 20000, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_offset (obj_c, c); + c->pop_pack (false); c->end_serialize(); } static void +populate_serializer_with_priority_overflow_expected (hb_serialize_context_t* c) +{ + std::string large_string(50000, 'a'); + c->start_serialize<char> (); + + unsigned obj_e = add_object ("e", 1, c); + + start_object (large_string.c_str (), 50000, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + unsigned obj_d = add_object ("d", 1, c); + + start_object (large_string.c_str (), 20000, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_offset (obj_c, c); + c->pop_pack (false); + + c->end_serialize(); +} + + +static void populate_serializer_with_dedup_overflow (hb_serialize_context_t* c) { std::string large_string(70000, 'a'); @@ -112,6 +209,526 @@ populate_serializer_with_dedup_overflow (hb_serialize_context_t* c) } static void +populate_serializer_with_isolation_overflow (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_4 = add_object ("4", 1, c); + + start_object (large_string.c_str(), 60000, c); + add_offset (obj_4, c); + unsigned obj_3 = c->pop_pack (false); + + start_object (large_string.c_str(), 10000, c); + add_offset (obj_4, c); + unsigned obj_2 = c->pop_pack (false); + + start_object ("1", 1, c); + add_wide_offset (obj_3, c); + add_offset (obj_2, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_isolation_overflow_complex (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_f = add_object ("f", 1, c); + + start_object ("e", 1, c); + add_offset (obj_f, c); + unsigned obj_e = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object ("d", 1, c); + add_offset (obj_e, c); + unsigned obj_d = c->pop_pack (false); + + start_object (large_string.c_str(), 60000, c); + add_offset (obj_d, c); + unsigned obj_h = c->pop_pack (false); + + start_object (large_string.c_str(), 60000, c); + add_offset (obj_c, c); + add_offset (obj_h, c); + unsigned obj_b = c->pop_pack (false); + + start_object (large_string.c_str(), 10000, c); + add_offset (obj_d, c); + unsigned obj_g = c->pop_pack (false); + + start_object (large_string.c_str(), 11000, c); + add_offset (obj_d, c); + unsigned obj_i = c->pop_pack (false); + + start_object ("a", 1, c); + add_wide_offset (obj_b, c); + add_offset (obj_g, c); + add_offset (obj_i, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_isolation_overflow_complex_expected (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + + // space 1 + + unsigned obj_f_prime = add_object ("f", 1, c); + + start_object ("e", 1, c); + add_offset (obj_f_prime, c); + unsigned obj_e_prime = c->pop_pack (false); + + start_object ("d", 1, c); + add_offset (obj_e_prime, c); + unsigned obj_d_prime = c->pop_pack (false); + + start_object (large_string.c_str(), 60000, c); + add_offset (obj_d_prime, c); + unsigned obj_h = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e_prime, c); + unsigned obj_c = c->pop_pack (false); + + start_object (large_string.c_str(), 60000, c); + add_offset (obj_c, c); + add_offset (obj_h, c); + unsigned obj_b = c->pop_pack (false); + + // space 0 + + unsigned obj_f = add_object ("f", 1, c); + + start_object ("e", 1, c); + add_offset (obj_f, c); + unsigned obj_e = c->pop_pack (false); + + + start_object ("d", 1, c); + add_offset (obj_e, c); + unsigned obj_d = c->pop_pack (false); + + start_object (large_string.c_str(), 11000, c); + add_offset (obj_d, c); + unsigned obj_i = c->pop_pack (false); + + start_object (large_string.c_str(), 10000, c); + add_offset (obj_d, c); + unsigned obj_g = c->pop_pack (false); + + start_object ("a", 1, c); + add_wide_offset (obj_b, c); + add_offset (obj_g, c); + add_offset (obj_i, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_isolation_overflow_spaces (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_d = add_object ("f", 1, c); + unsigned obj_e = add_object ("f", 1, c); + + start_object (large_string.c_str(), 60000, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (); + + start_object (large_string.c_str(), 60000, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (); + + + start_object ("a", 1, c); + add_wide_offset (obj_b, c); + add_wide_offset (obj_c, c); + c->pop_pack (); + + c->end_serialize(); +} + +static void +populate_serializer_spaces (hb_serialize_context_t* c, bool with_overflow) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_i; + + if (with_overflow) + obj_i = add_object ("i", 1, c); + + // Space 2 + unsigned obj_h = add_object ("h", 1, c); + + start_object (large_string.c_str(), 30000, c); + add_offset (obj_h, c); + unsigned obj_e = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_e, c); + unsigned obj_b = c->pop_pack (false); + + // Space 1 + if (!with_overflow) + obj_i = add_object ("i", 1, c); + + start_object (large_string.c_str(), 30000, c); + add_offset (obj_i, c); + unsigned obj_g = c->pop_pack (false); + + start_object (large_string.c_str(), 30000, c); + add_offset (obj_i, c); + unsigned obj_f = c->pop_pack (false); + + start_object ("d", 1, c); + add_offset (obj_g, c); + unsigned obj_d = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_f, c); + unsigned obj_c = c->pop_pack (false); + + start_object ("a", 1, c); + add_wide_offset (obj_b, c); + add_wide_offset (obj_c, c); + add_wide_offset (obj_d, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_spaces_16bit_connection (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_g = add_object ("g", 1, c); + unsigned obj_h = add_object ("h", 1, c); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_g, c); + unsigned obj_e = c->pop_pack (false); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_h, c); + unsigned obj_f = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object ("d", 1, c); + add_offset (obj_f, c); + unsigned obj_d = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_e, c); + add_offset (obj_h, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_wide_offset (obj_c, c); + add_wide_offset (obj_d, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_spaces_16bit_connection_expected (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_g_prime = add_object ("g", 1, c); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_g_prime, c); + unsigned obj_e_prime = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e_prime, c); + unsigned obj_c = c->pop_pack (false); + + unsigned obj_h_prime = add_object ("h", 1, c); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_h_prime, c); + unsigned obj_f = c->pop_pack (false); + + start_object ("d", 1, c); + add_offset (obj_f, c); + unsigned obj_d = c->pop_pack (false); + + unsigned obj_g = add_object ("g", 1, c); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_g, c); + unsigned obj_e = c->pop_pack (false); + + unsigned obj_h = add_object ("h", 1, c); + + start_object ("b", 1, c); + add_offset (obj_e, c); + add_offset (obj_h, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_wide_offset (obj_c, c); + add_wide_offset (obj_d, c); + c->pop_pack (false); + + c->end_serialize (); +} + +static void +populate_serializer_short_and_wide_subgraph_root (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_e = add_object ("e", 1, c); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_c, c); + unsigned obj_d = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_c, c); + add_offset (obj_e, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_wide_offset (obj_c, c); + add_wide_offset (obj_d, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_short_and_wide_subgraph_root_expected (hb_serialize_context_t* c) +{ + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_e_prime = add_object ("e", 1, c); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_e_prime, c); + unsigned obj_c_prime = c->pop_pack (false); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_c_prime, c); + unsigned obj_d = c->pop_pack (false); + + unsigned obj_e = add_object ("e", 1, c); + + start_object (large_string.c_str (), 40000, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + + start_object ("b", 1, c); + add_offset (obj_c, c); + add_offset (obj_e, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_wide_offset (obj_c_prime, c); + add_wide_offset (obj_d, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_split_spaces (hb_serialize_context_t* c) +{ + // Overflow needs to be resolved by splitting the single space + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_f = add_object ("f", 1, c); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f, c); + unsigned obj_d = c->pop_pack (false); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f, c); + unsigned obj_e = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object ("a", 1, c); + add_wide_offset (obj_b, c); + add_wide_offset (obj_c, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_split_spaces_2 (hb_serialize_context_t* c) +{ + // Overflow needs to be resolved by splitting the single space + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_f = add_object ("f", 1, c); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f, c); + unsigned obj_d = c->pop_pack (false); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f, c); + unsigned obj_e = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_wide_offset (obj_b, c); + add_wide_offset (obj_c, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_split_spaces_expected (hb_serialize_context_t* c) +{ + // Overflow needs to be resolved by splitting the single space + + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + unsigned obj_f_prime = add_object ("f", 1, c); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f_prime, c); + unsigned obj_d = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (false); + + unsigned obj_f = add_object ("f", 1, c); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f, c); + unsigned obj_e = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object ("a", 1, c); + add_wide_offset (obj_b, c); + add_wide_offset (obj_c, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_with_split_spaces_expected_2 (hb_serialize_context_t* c) +{ + // Overflow needs to be resolved by splitting the single space + + std::string large_string(70000, 'a'); + c->start_serialize<char> (); + + // Space 2 + + unsigned obj_f_double_prime = add_object ("f", 1, c); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f_double_prime, c); + unsigned obj_d_prime = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_d_prime, c); + unsigned obj_b_prime = c->pop_pack (false); + + // Space 1 + + unsigned obj_f_prime = add_object ("f", 1, c); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f_prime, c); + unsigned obj_e = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + // Space 0 + + unsigned obj_f = add_object ("f", 1, c); + + start_object (large_string.c_str(), 40000, c); + add_offset (obj_f, c); + unsigned obj_d = c->pop_pack (false); + + start_object ("b", 1, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (false); + + // Root + start_object ("a", 1, c); + add_offset (obj_b, c); + add_wide_offset (obj_b_prime, c); + add_wide_offset (obj_c, c); + c->pop_pack (false); + + c->end_serialize(); +} + +static void populate_serializer_complex_1 (hb_serialize_context_t* c) { c->start_serialize<char> (); @@ -126,7 +743,7 @@ populate_serializer_complex_1 (hb_serialize_context_t* c) start_object ("abc", 3, c); add_offset (obj_2, c); add_offset (obj_4, c); - c->pop_pack (); + c->pop_pack (false); c->end_serialize(); } @@ -152,7 +769,7 @@ populate_serializer_complex_2 (hb_serialize_context_t* c) add_offset (obj_2, c); add_offset (obj_4, c); add_offset (obj_5, c); - c->pop_pack (); + c->pop_pack (false); c->end_serialize(); } @@ -182,7 +799,34 @@ populate_serializer_complex_3 (hb_serialize_context_t* c) add_offset (obj_2, c); add_offset (obj_4, c); add_offset (obj_5, c); - c->pop_pack (); + c->pop_pack (false); + + c->end_serialize(); +} + +static void +populate_serializer_virtual_link (hb_serialize_context_t* c) +{ + c->start_serialize<char> (); + + unsigned obj_d = add_object ("d", 1, c); + + start_object ("b", 1, c); + add_offset (obj_d, c); + unsigned obj_b = c->pop_pack (false); + + start_object ("e", 1, c); + add_virtual_offset (obj_b, c); + unsigned obj_e = c->pop_pack (false); + + start_object ("c", 1, c); + add_offset (obj_e, c); + unsigned obj_c = c->pop_pack (false); + + start_object ("a", 1, c); + add_offset (obj_b, c); + add_offset (obj_c, c); + c->pop_pack (false); c->end_serialize(); } @@ -198,19 +842,19 @@ static void test_sort_kahn_1 () graph.sort_kahn (); assert(strncmp (graph.object (3).head, "abc", 3) == 0); - assert(graph.object (3).links.length == 2); - assert(graph.object (3).links[0].objidx == 2); - assert(graph.object (3).links[1].objidx == 1); + assert(graph.object (3).real_links.length == 2); + assert(graph.object (3).real_links[0].objidx == 2); + assert(graph.object (3).real_links[1].objidx == 1); assert(strncmp (graph.object (2).head, "def", 3) == 0); - assert(graph.object (2).links.length == 1); - assert(graph.object (2).links[0].objidx == 0); + assert(graph.object (2).real_links.length == 1); + assert(graph.object (2).real_links[0].objidx == 0); assert(strncmp (graph.object (1).head, "jkl", 3) == 0); - assert(graph.object (1).links.length == 0); + assert(graph.object (1).real_links.length == 0); assert(strncmp (graph.object (0).head, "ghi", 3) == 0); - assert(graph.object (0).links.length == 0); + assert(graph.object (0).real_links.length == 0); free (buffer); } @@ -227,24 +871,24 @@ static void test_sort_kahn_2 () assert(strncmp (graph.object (4).head, "abc", 3) == 0); - assert(graph.object (4).links.length == 3); - assert(graph.object (4).links[0].objidx == 3); - assert(graph.object (4).links[1].objidx == 0); - assert(graph.object (4).links[2].objidx == 2); + assert(graph.object (4).real_links.length == 3); + assert(graph.object (4).real_links[0].objidx == 3); + assert(graph.object (4).real_links[1].objidx == 0); + assert(graph.object (4).real_links[2].objidx == 2); assert(strncmp (graph.object (3).head, "def", 3) == 0); - assert(graph.object (3).links.length == 1); - assert(graph.object (3).links[0].objidx == 1); + assert(graph.object (3).real_links.length == 1); + assert(graph.object (3).real_links[0].objidx == 1); assert(strncmp (graph.object (2).head, "mn", 2) == 0); - assert(graph.object (2).links.length == 0); + assert(graph.object (2).real_links.length == 0); assert(strncmp (graph.object (1).head, "ghi", 3) == 0); - assert(graph.object (1).links.length == 1); - assert(graph.object (1).links[0].objidx == 0); + assert(graph.object (1).real_links.length == 1); + assert(graph.object (1).real_links[0].objidx == 0); assert(strncmp (graph.object (0).head, "jkl", 3) == 0); - assert(graph.object (0).links.length == 0); + assert(graph.object (0).real_links.length == 0); free (buffer); } @@ -260,24 +904,24 @@ static void test_sort_shortest () graph.sort_shortest_distance (); assert(strncmp (graph.object (4).head, "abc", 3) == 0); - assert(graph.object (4).links.length == 3); - assert(graph.object (4).links[0].objidx == 2); - assert(graph.object (4).links[1].objidx == 0); - assert(graph.object (4).links[2].objidx == 3); + assert(graph.object (4).real_links.length == 3); + assert(graph.object (4).real_links[0].objidx == 2); + assert(graph.object (4).real_links[1].objidx == 0); + assert(graph.object (4).real_links[2].objidx == 3); assert(strncmp (graph.object (3).head, "mn", 2) == 0); - assert(graph.object (3).links.length == 0); + assert(graph.object (3).real_links.length == 0); assert(strncmp (graph.object (2).head, "def", 3) == 0); - assert(graph.object (2).links.length == 1); - assert(graph.object (2).links[0].objidx == 1); + assert(graph.object (2).real_links.length == 1); + assert(graph.object (2).real_links[0].objidx == 1); assert(strncmp (graph.object (1).head, "ghi", 3) == 0); - assert(graph.object (1).links.length == 1); - assert(graph.object (1).links[0].objidx == 0); + assert(graph.object (1).real_links.length == 1); + assert(graph.object (1).real_links[0].objidx == 0); assert(strncmp (graph.object (0).head, "jkl", 3) == 0); - assert(graph.object (0).links.length == 0); + assert(graph.object (0).real_links.length == 0); free (buffer); } @@ -293,27 +937,27 @@ static void test_duplicate_leaf () graph.duplicate (4, 1); assert(strncmp (graph.object (5).head, "abc", 3) == 0); - assert(graph.object (5).links.length == 3); - assert(graph.object (5).links[0].objidx == 3); - assert(graph.object (5).links[1].objidx == 4); - assert(graph.object (5).links[2].objidx == 0); + assert(graph.object (5).real_links.length == 3); + assert(graph.object (5).real_links[0].objidx == 3); + assert(graph.object (5).real_links[1].objidx == 4); + assert(graph.object (5).real_links[2].objidx == 0); assert(strncmp (graph.object (4).head, "jkl", 3) == 0); - assert(graph.object (4).links.length == 0); + assert(graph.object (4).real_links.length == 0); assert(strncmp (graph.object (3).head, "def", 3) == 0); - assert(graph.object (3).links.length == 1); - assert(graph.object (3).links[0].objidx == 2); + assert(graph.object (3).real_links.length == 1); + assert(graph.object (3).real_links[0].objidx == 2); assert(strncmp (graph.object (2).head, "ghi", 3) == 0); - assert(graph.object (2).links.length == 1); - assert(graph.object (2).links[0].objidx == 1); + assert(graph.object (2).real_links.length == 1); + assert(graph.object (2).real_links[0].objidx == 1); assert(strncmp (graph.object (1).head, "jkl", 3) == 0); - assert(graph.object (1).links.length == 0); + assert(graph.object (1).real_links.length == 0); assert(strncmp (graph.object (0).head, "mn", 2) == 0); - assert(graph.object (0).links.length == 0); + assert(graph.object (0).real_links.length == 0); free (buffer); } @@ -329,32 +973,32 @@ static void test_duplicate_interior () graph.duplicate (3, 2); assert(strncmp (graph.object (6).head, "abc", 3) == 0); - assert(graph.object (6).links.length == 3); - assert(graph.object (6).links[0].objidx == 4); - assert(graph.object (6).links[1].objidx == 2); - assert(graph.object (6).links[2].objidx == 1); + assert(graph.object (6).real_links.length == 3); + assert(graph.object (6).real_links[0].objidx == 4); + assert(graph.object (6).real_links[1].objidx == 2); + assert(graph.object (6).real_links[2].objidx == 1); assert(strncmp (graph.object (5).head, "jkl", 3) == 0); - assert(graph.object (5).links.length == 1); - assert(graph.object (5).links[0].objidx == 0); + assert(graph.object (5).real_links.length == 1); + assert(graph.object (5).real_links[0].objidx == 0); assert(strncmp (graph.object (4).head, "def", 3) == 0); - assert(graph.object (4).links.length == 1); - assert(graph.object (4).links[0].objidx == 3); + assert(graph.object (4).real_links.length == 1); + assert(graph.object (4).real_links[0].objidx == 3); assert(strncmp (graph.object (3).head, "ghi", 3) == 0); - assert(graph.object (3).links.length == 1); - assert(graph.object (3).links[0].objidx == 5); + assert(graph.object (3).real_links.length == 1); + assert(graph.object (3).real_links[0].objidx == 5); assert(strncmp (graph.object (2).head, "jkl", 3) == 0); - assert(graph.object (2).links.length == 1); - assert(graph.object (2).links[0].objidx == 0); + assert(graph.object (2).real_links.length == 1); + assert(graph.object (2).real_links[0].objidx == 0); assert(strncmp (graph.object (1).head, "mn", 2) == 0); - assert(graph.object (1).links.length == 0); + assert(graph.object (1).real_links.length == 0); assert(strncmp (graph.object (0).head, "opqrst", 6) == 0); - assert(graph.object (0).links.length == 0); + assert(graph.object (0).real_links.length == 0); free (buffer); } @@ -368,19 +1012,14 @@ test_serialize () populate_serializer_simple (&c1); hb_bytes_t expected = c1.copy_bytes (); - void* buffer_2 = malloc (buffer_size); - hb_serialize_context_t c2 (buffer_2, buffer_size); - graph_t graph (c1.object_graph ()); - graph.serialize (&c2); - hb_bytes_t actual = c2.copy_bytes (); + hb_blob_t* out = graph.serialize (); + free (buffer_1); + hb_bytes_t actual = out->as_bytes (); assert (actual == expected); - - actual.fini (); expected.fini (); - free (buffer_1); - free (buffer_2); + hb_blob_destroy (out); } static void test_will_overflow_1 () @@ -430,17 +1069,13 @@ static void test_resolve_overflows_via_sort () populate_serializer_with_overflow (&c); graph_t graph (c.object_graph ()); - void* out_buffer = malloc (buffer_size); - hb_serialize_context_t out (out_buffer, buffer_size); - - hb_resolve_overflows (c.object_graph (), &out); - assert (!out.offset_overflow ()); - hb_bytes_t result = out.copy_bytes (); + hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE); + assert (out); + hb_bytes_t result = out->as_bytes (); assert (result.length == (80000 + 3 + 3 * 2)); - result.fini (); free (buffer); - free (out_buffer); + hb_blob_destroy (out); } static void test_resolve_overflows_via_duplication () @@ -451,21 +1086,250 @@ static void test_resolve_overflows_via_duplication () populate_serializer_with_dedup_overflow (&c); graph_t graph (c.object_graph ()); - void* out_buffer = malloc (buffer_size); - hb_serialize_context_t out (out_buffer, buffer_size); - - hb_resolve_overflows (c.object_graph (), &out); - assert (!out.offset_overflow ()); - hb_bytes_t result = out.copy_bytes (); + hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE); + assert (out); + hb_bytes_t result = out->as_bytes (); assert (result.length == (10000 + 2 * 2 + 60000 + 2 + 3 * 2)); - result.fini (); free (buffer); - free (out_buffer); + hb_blob_destroy (out); } +static void test_resolve_overflows_via_space_assignment () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_spaces (&c, true); + + void* expected_buffer = malloc (buffer_size); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_spaces (&e, false); + + run_resolve_overflow_test ("test_resolve_overflows_via_space_assignment", + c, + e); + + free (buffer); + free (expected_buffer); +} + +static void test_resolve_overflows_via_isolation () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_isolation_overflow (&c); + graph_t graph (c.object_graph ()); + + assert (c.offset_overflow ()); + hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0); + assert (out); + hb_bytes_t result = out->as_bytes (); + assert (result.length == (1 + 10000 + 60000 + 1 + 1 + + 4 + 3 * 2)); + + free (buffer); + hb_blob_destroy (out); +} + +static void test_resolve_overflows_via_isolation_with_recursive_duplication () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_isolation_overflow_complex (&c); + + void* expected_buffer = malloc (buffer_size); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_with_isolation_overflow_complex_expected (&e); + + run_resolve_overflow_test ("test_resolve_overflows_via_isolation_with_recursive_duplication", + c, + e); + free (buffer); + free (expected_buffer); +} + +static void test_resolve_overflows_via_isolating_16bit_space () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_spaces_16bit_connection (&c); + + void* expected_buffer = malloc (buffer_size); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_spaces_16bit_connection_expected (&e); + + run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space", + c, + e); + + free (buffer); + free (expected_buffer); +} + +static void test_resolve_overflows_via_isolating_16bit_space_2 () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_short_and_wide_subgraph_root (&c); + + void* expected_buffer = malloc (buffer_size); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_short_and_wide_subgraph_root_expected (&e); + + run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space_2", + c, + e); + + free (buffer); + free (expected_buffer); +} + +static void test_resolve_overflows_via_isolation_spaces () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_isolation_overflow_spaces (&c); + graph_t graph (c.object_graph ()); + + assert (c.offset_overflow ()); + hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0); + assert (out); + hb_bytes_t result = out->as_bytes (); + + unsigned expected_length = 3 + 2 * 60000; // objects + expected_length += 2 * 4 + 2 * 2; // links + assert (result.length == expected_length); + + free (buffer); + hb_blob_destroy (out); +} + +static void test_resolve_overflows_via_splitting_spaces () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_split_spaces (&c); + + void* expected_buffer = malloc (buffer_size); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_with_split_spaces_expected (&e); + + run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces", + c, + e, + 1); + + free (buffer); + free (expected_buffer); + +} + +static void test_resolve_overflows_via_splitting_spaces_2 () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_split_spaces_2 (&c); + + void* expected_buffer = malloc (buffer_size); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_with_split_spaces_expected_2 (&e); + + run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces_2", + c, + e, + 1); + free (buffer); + free (expected_buffer); +} + +static void test_resolve_overflows_via_priority () +{ + size_t buffer_size = 160000; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_with_priority_overflow (&c); + + void* expected_buffer = malloc (buffer_size); + hb_serialize_context_t e (expected_buffer, buffer_size); + populate_serializer_with_priority_overflow_expected (&e); + + run_resolve_overflow_test ("test_resolve_overflows_via_priority", + c, + e, + 3); + free (buffer); + free (expected_buffer); +} + + +static void test_virtual_link () +{ + size_t buffer_size = 100; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + populate_serializer_virtual_link (&c); + + hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE); + assert (out); + + hb_bytes_t result = out->as_bytes (); + assert (result.length == 5 + 4 * 2); + assert (result[0] == 'a'); + assert (result[5] == 'c'); + assert (result[8] == 'e'); + assert (result[9] == 'b'); + assert (result[12] == 'd'); + + free (buffer); + hb_blob_destroy (out); +} + +static void +test_shared_node_with_virtual_links () +{ + size_t buffer_size = 100; + void* buffer = malloc (buffer_size); + hb_serialize_context_t c (buffer, buffer_size); + + c.start_serialize<char> (); + + unsigned obj_b = add_object ("b", 1, &c); + unsigned obj_c = add_object ("c", 1, &c); + + start_object ("d", 1, &c); + add_virtual_offset (obj_b, &c); + unsigned obj_d_1 = c.pop_pack (); + + start_object ("d", 1, &c); + add_virtual_offset (obj_c, &c); + unsigned obj_d_2 = c.pop_pack (); + + assert (obj_d_1 == obj_d_2); + + start_object ("a", 1, &c); + add_offset (obj_b, &c); + add_offset (obj_c, &c); + add_offset (obj_d_1, &c); + add_offset (obj_d_2, &c); + c.pop_pack (); + c.end_serialize (); + + assert(c.object_graph() [obj_d_1]->virtual_links.length == 2); + assert(c.object_graph() [obj_d_1]->virtual_links[0].objidx == obj_b); + assert(c.object_graph() [obj_d_1]->virtual_links[1].objidx == obj_c); + free(buffer); +} + + // TODO(garretrieger): update will_overflow tests to check the overflows array. -// TODO(garretrieger): add a test(s) using a real font. // TODO(garretrieger): add tests for priority raising. int @@ -480,6 +1344,17 @@ main (int argc, char **argv) test_will_overflow_3 (); test_resolve_overflows_via_sort (); test_resolve_overflows_via_duplication (); + test_resolve_overflows_via_priority (); + test_resolve_overflows_via_space_assignment (); + test_resolve_overflows_via_isolation (); + test_resolve_overflows_via_isolation_with_recursive_duplication (); + test_resolve_overflows_via_isolation_spaces (); + test_resolve_overflows_via_isolating_16bit_space (); + test_resolve_overflows_via_isolating_16bit_space_2 (); + test_resolve_overflows_via_splitting_spaces (); + test_resolve_overflows_via_splitting_spaces_2 (); test_duplicate_leaf (); test_duplicate_interior (); + test_virtual_link (); + test_shared_node_with_virtual_links (); } |