[repacker] Add test for virtual links in the repacker.
diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh
index f4c8fab..328c7b4 100644
--- a/src/hb-serialize.hh
+++ b/src/hb-serialize.hh
@@ -364,6 +364,30 @@
assert (packed.tail ()->head == tail);
}
+ void add_link (VirtualOffset &ofs, objidx_t objidx)
+ {
+ // This link is not associated with an actual offset and exists merely to enforce
+ // an ordering constraint.
+ if (unlikely (in_error ())) return;
+
+ if (!objidx)
+ return;
+
+ assert (current);
+ assert (current->head <= (const char *) &ofs);
+
+ auto& link = *current->links.push ();
+ if (current->links.in_error ())
+ err (HB_SERIALIZE_ERROR_OTHER);
+
+ link.width = 0;
+ link.objidx = objidx;
+ link.is_signed = 0;
+ link.whence = 0;
+ link.position = 0;
+ link.bias = 0;
+ }
+
template <typename T>
void add_link (T &ofs, objidx_t objidx,
whence_t whence = Head,
diff --git a/src/test-repacker.cc b/src/test-repacker.cc
index aa48725..66e5aa1 100644
--- a/src/test-repacker.cc
+++ b/src/test-repacker.cc
@@ -97,6 +97,13 @@
free (out_buffer);
}
+static void add_virtual_offset (unsigned id,
+ hb_serialize_context_t* c)
+{
+ VirtualOffset* offset = c->start_embed<VirtualOffset> ();
+ c->add_link (*offset, id);
+}
+
static void
populate_serializer_simple (hb_serialize_context_t* c)
{
@@ -748,6 +755,33 @@
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 ();
+
+ start_object ("e", 1, c);
+ add_virtual_offset (obj_b, c);
+ unsigned obj_e = c->pop_pack();
+
+ start_object ("c", 1, c);
+ add_offset (obj_e, c);
+ unsigned obj_c = c->pop_pack ();
+
+ start_object ("a", 1, c);
+ add_offset (obj_b, c);
+ add_offset (obj_c, c);
+ c->pop_pack ();
+
+ c->end_serialize();
+}
+
static void test_sort_kahn_1 ()
{
size_t buffer_size = 100;
@@ -1186,7 +1220,32 @@
1);
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);
+
+ void* out_buffer = malloc (buffer_size);
+ hb_serialize_context_t out (out_buffer, buffer_size);
+
+ hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, &out);
+ assert (!out.offset_overflow ());
+
+ hb_bytes_t result = out.copy_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');
+
+ result.fini ();
+ free (buffer);
+ free (out_buffer);
}
// TODO(garretrieger): update will_overflow tests to check the overflows array.
@@ -1214,4 +1273,5 @@
test_resolve_overflows_via_splitting_spaces_2 ();
test_duplicate_leaf ();
test_duplicate_interior ();
+ test_virtual_link ();
}