summaryrefslogtreecommitdiff
path: root/thirdparty/harfbuzz/src/hb-serialize.hh
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/harfbuzz/src/hb-serialize.hh')
-rw-r--r--thirdparty/harfbuzz/src/hb-serialize.hh55
1 files changed, 39 insertions, 16 deletions
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index d22ae06087..823c0be8b5 100644
--- a/thirdparty/harfbuzz/src/hb-serialize.hh
+++ b/thirdparty/harfbuzz/src/hb-serialize.hh
@@ -65,19 +65,26 @@ struct hb_serialize_context_t
struct object_t
{
- void fini () { links.fini (); }
+ void fini () {
+ real_links.fini ();
+ virtual_links.fini ();
+ }
bool operator == (const object_t &o) const
{
+ // Virtual links aren't considered for equality since they don't affect the functionality
+ // of the object.
return (tail - head == o.tail - o.head)
- && (links.length == o.links.length)
+ && (real_links.length == o.real_links.length)
&& 0 == hb_memcmp (head, o.head, tail - head)
- && links.as_bytes () == o.links.as_bytes ();
+ && real_links.as_bytes () == o.real_links.as_bytes ();
}
uint32_t hash () const
{
+ // Virtual links aren't considered for equality since they don't affect the functionality
+ // of the object.
return hb_bytes_t (head, tail - head).hash () ^
- links.as_bytes ().hash ();
+ real_links.as_bytes ().hash ();
}
struct link_t
@@ -92,8 +99,14 @@ struct hb_serialize_context_t
char *head;
char *tail;
- hb_vector_t<link_t> links;
+ hb_vector_t<link_t> real_links;
+ hb_vector_t<link_t> virtual_links;
object_t *next;
+
+ auto all_links () const HB_AUTO_RETURN
+ (( hb_concat (this->real_links, this->virtual_links) ));
+ auto all_links_writer () HB_AUTO_RETURN
+ (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) ));
};
struct snapshot_t
@@ -101,12 +114,14 @@ struct hb_serialize_context_t
char *head;
char *tail;
object_t *current; // Just for sanity check
- unsigned num_links;
+ unsigned num_real_links;
+ unsigned num_virtual_links;
hb_serialize_error_t errors;
};
snapshot_t snapshot ()
- { return snapshot_t { head, tail, current, current->links.length, errors }; }
+ { return snapshot_t {
+ head, tail, current, current->real_links.length, current->virtual_links.length, errors }; }
hb_serialize_context_t (void *start_, unsigned int size) :
start ((char *) start_),
@@ -282,7 +297,8 @@ struct hb_serialize_context_t
if (!len)
{
- assert (!obj->links.length);
+ assert (!obj->real_links.length);
+ assert (!obj->virtual_links.length);
return 0;
}
@@ -292,6 +308,7 @@ struct hb_serialize_context_t
objidx = packed_map.get (obj);
if (objidx)
{
+ merge_virtual_links (obj, objidx);
obj->fini ();
return objidx;
}
@@ -327,7 +344,8 @@ struct hb_serialize_context_t
// Overflows that happened after the snapshot will be erased by the revert.
if (unlikely (in_error () && !only_overflow ())) return;
assert (snap.current == current);
- current->links.shrink (snap.num_links);
+ current->real_links.shrink (snap.num_real_links);
+ current->virtual_links.shrink (snap.num_virtual_links);
errors = snap.errors;
revert (snap.head, snap.tail);
}
@@ -375,8 +393,8 @@ struct hb_serialize_context_t
assert (current);
- auto& link = *current->links.push ();
- if (current->links.in_error ())
+ auto& link = *current->virtual_links.push ();
+ if (current->virtual_links.in_error ())
err (HB_SERIALIZE_ERROR_OTHER);
link.width = 0;
@@ -400,8 +418,8 @@ struct hb_serialize_context_t
assert (current);
assert (current->head <= (const char *) &ofs);
- auto& link = *current->links.push ();
- if (current->links.in_error ())
+ auto& link = *current->real_links.push ();
+ if (current->real_links.in_error ())
err (HB_SERIALIZE_ERROR_OTHER);
link.width = sizeof (T);
@@ -440,10 +458,8 @@ struct hb_serialize_context_t
assert (packed.length > 1);
for (const object_t* parent : ++hb_iter (packed))
- for (const object_t::link_t &link : parent->links)
+ for (const object_t::link_t &link : parent->real_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;
@@ -642,6 +658,13 @@ struct hb_serialize_context_t
private:
+ void merge_virtual_links (const object_t* from, objidx_t to_idx) {
+ object_t* to = packed[to_idx];
+ for (const auto& l : from->virtual_links) {
+ to->virtual_links.push (l);
+ }
+ }
+
/* Object memory pool. */
hb_pool_t<object_t> object_pool;