[repacker] add 'virtual links' to the serializer.

These aren't associated with an offset field, but instead exist solely to add an ordering constraint to the object graph.
pull/3281/head
Garret Rieger 3 years ago
parent 59d8f6c817
commit 7615b94ecf
  1. 10
      src/hb-repacker.hh
  2. 21
      src/hb-serialize.hh

@ -828,8 +828,9 @@ struct graph_t
if (visited[link.objidx]) continue;
const auto& child = vertices_[link.objidx].obj;
unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
int64_t child_weight = (child.tail - child.head) +
((int64_t) 1 << (link.width * 8)) * (vertices_[link.objidx].space + 1);
((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
int64_t child_distance = next_distance + child_weight;
if (child_distance < vertices_[link.objidx].distance)
@ -874,6 +875,10 @@ struct graph_t
bool is_valid_offset (int64_t offset,
const hb_serialize_context_t::object_t::link_t& link) const
{
if (unlikely (!link.width))
// Virtual links can't overflow.
return link.is_signed || offset >= 0;
if (link.is_signed)
{
if (link.width == 4)
@ -966,6 +971,9 @@ struct graph_t
{
switch (link.width)
{
case 0:
// Virtual links aren't serialized.
return;
case 4:
if (link.is_signed)
{

@ -51,6 +51,12 @@ enum hb_serialize_error_t {
};
HB_MARK_AS_FLAG_T (hb_serialize_error_t);
// This is a 0 byte wide offset, used to add virtual links to the serializer object graph.
// It does not correspond to a real offset and exists soley to enforce an ordering constraint
// in the graph's packed order.
struct VirtualOffset {
};
struct hb_serialize_context_t
{
typedef unsigned objidx_t;
@ -376,11 +382,22 @@ struct hb_serialize_context_t
err (HB_SERIALIZE_ERROR_OTHER);
link.width = sizeof (T);
link.objidx = objidx;
if (unlikely (!sizeof (T)))
{
// This link is not associated with an actual offset and exists merely to enforce
// an ordering constraint.
link.is_signed = 0;
link.whence = 0;
link.position = 0;
link.bias = 0;
return;
}
link.is_signed = std::is_signed<hb_unwrap_type (T)>::value;
link.whence = (unsigned) whence;
link.position = (const char *) &ofs - current->head;
link.bias = bias;
link.objidx = objidx;
}
unsigned to_bias (const void *base) const
@ -402,6 +419,8 @@ struct hb_serialize_context_t
for (const object_t* parent : ++hb_iter (packed))
for (const object_t::link_t &link : parent->links)
{
if (unlikely (!link.width)) continue; // Don't need to resolve virtual offsets
const object_t* child = packed[link.objidx];
if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; }
unsigned offset = 0;

Loading…
Cancel
Save