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.hh69
1 files changed, 46 insertions, 23 deletions
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index d22ae06087..6615f033c5 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_),
@@ -264,7 +279,7 @@ struct hb_serialize_context_t
object_pool.release (obj);
}
- /* Set share to false when an object is unlikely sharable with others
+ /* Set share to false when an object is unlikely shareable with others
* so not worth an attempt, or a contiguous table is serialized as
* multiple consecutive objects in the reverse order so can't be shared.
*/
@@ -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);
}
@@ -363,7 +381,7 @@ struct hb_serialize_context_t
// Adding a virtual link from object a to object b will ensure that object b is always packed after
// object a in the final serialized order.
//
- // This is useful in certain situtations where there needs to be a specific ordering in the
+ // This is useful in certain situations where there needs to be a specific ordering in the
// final serialization. Such as when platform bugs require certain orderings, or to provide
// guidance to the repacker for better offset overflow resolution.
void add_virtual_link (objidx_t objidx)
@@ -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;
@@ -494,7 +510,7 @@ struct hb_serialize_context_t
{ return reinterpret_cast<Type *> (this->head); }
template <typename Type>
Type *start_embed (const Type &obj) const
- { return start_embed (hb_addressof (obj)); }
+ { return start_embed (std::addressof (obj)); }
bool err (hb_serialize_error_t err_type)
{
@@ -532,7 +548,7 @@ struct hb_serialize_context_t
}
template <typename Type>
Type *embed (const Type &obj)
- { return embed (hb_addressof (obj)); }
+ { return embed (std::addressof (obj)); }
template <typename Type, typename ...Ts> auto
_copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
@@ -579,19 +595,19 @@ struct hb_serialize_context_t
}
template <typename Type>
Type *extend_size (Type &obj, size_t size)
- { return extend_size (hb_addressof (obj), size); }
+ { return extend_size (std::addressof (obj), size); }
template <typename Type>
Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
template <typename Type>
- Type *extend_min (Type &obj) { return extend_min (hb_addressof (obj)); }
+ Type *extend_min (Type &obj) { return extend_min (std::addressof (obj)); }
template <typename Type, typename ...Ts>
Type *extend (Type *obj, Ts&&... ds)
{ return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); }
template <typename Type, typename ...Ts>
Type *extend (Type &obj, Ts&&... ds)
- { return extend (hb_addressof (obj), std::forward<Ts> (ds)...); }
+ { return extend (std::addressof (obj), std::forward<Ts> (ds)...); }
/* Output routines. */
hb_bytes_t copy_bytes () const
@@ -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;