Merge pull request #2163 from harfbuzz/absolute-link
added add_link_abs()
This commit is contained in:
commit
c21eb86bfd
|
@ -338,11 +338,15 @@ struct OffsetTo : Offset<OffsetType, has_null>
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
|
/* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
|
||||||
|
/* Workaround clang bug: https://bugs.llvm.org/show_bug.cgi?id=23029
|
||||||
|
* Can't compile: whence = hb_serialize_context_t::Head followed by Ts&&...
|
||||||
|
*/
|
||||||
template <typename ...Ts>
|
template <typename ...Ts>
|
||||||
bool serialize_copy (hb_serialize_context_t *c,
|
bool serialize_copy (hb_serialize_context_t *c,
|
||||||
const OffsetTo& src,
|
const OffsetTo& src,
|
||||||
const void *src_base,
|
const void *src_base,
|
||||||
const void *dst_base,
|
const void *dst_base,
|
||||||
|
hb_serialize_context_t::whence_t whence,
|
||||||
Ts&&... ds)
|
Ts&&... ds)
|
||||||
{
|
{
|
||||||
*this = 0;
|
*this = 0;
|
||||||
|
@ -353,11 +357,17 @@ struct OffsetTo : Offset<OffsetType, has_null>
|
||||||
|
|
||||||
bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...);
|
bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...);
|
||||||
|
|
||||||
c->add_link (*this, c->pop_pack (), dst_base);
|
c->add_link (*this, c->pop_pack (), dst_base, whence);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool serialize_copy (hb_serialize_context_t *c,
|
||||||
|
const OffsetTo& src,
|
||||||
|
const void *src_base,
|
||||||
|
const void *dst_base)
|
||||||
|
{ return serialize_copy (c, src, src_base, dst_base, hb_serialize_context_t::Head); }
|
||||||
|
|
||||||
bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
|
bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
|
|
@ -98,13 +98,12 @@ struct NameRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
NameRecord* copy (hb_serialize_context_t *c,
|
NameRecord* copy (hb_serialize_context_t *c,
|
||||||
const void *src_base,
|
const void *src_base) const
|
||||||
const void *dst_base) const
|
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
auto *out = c->embed (this);
|
auto *out = c->embed (this);
|
||||||
if (unlikely (!out)) return_trace (nullptr);
|
if (unlikely (!out)) return_trace (nullptr);
|
||||||
out->offset.serialize_copy (c, offset, src_base, dst_base, length);
|
out->offset.serialize_copy (c, offset, src_base, nullptr, hb_serialize_context_t::Tail, length);
|
||||||
return_trace (out);
|
return_trace (out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,13 +215,6 @@ struct name
|
||||||
this->format = 0;
|
this->format = 0;
|
||||||
this->count = it.len ();
|
this->count = it.len ();
|
||||||
|
|
||||||
auto snap = c->snapshot ();
|
|
||||||
this->nameRecordZ.serialize (c, this->count);
|
|
||||||
if (unlikely (!c->check_assign (this->stringOffset, c->length ()))) return_trace (false);
|
|
||||||
c->revert (snap);
|
|
||||||
|
|
||||||
const void *dst_string_pool = &(this + this->stringOffset);
|
|
||||||
|
|
||||||
NameRecord *name_records = (NameRecord *) calloc (it.len (), NameRecord::static_size);
|
NameRecord *name_records = (NameRecord *) calloc (it.len (), NameRecord::static_size);
|
||||||
hb_array_t<NameRecord> records (name_records, it.len ());
|
hb_array_t<NameRecord> records (name_records, it.len ());
|
||||||
|
|
||||||
|
@ -234,12 +226,12 @@ struct name
|
||||||
|
|
||||||
records.qsort ();
|
records.qsort ();
|
||||||
|
|
||||||
c->copy_all (records, src_string_pool, dst_string_pool);
|
c->copy_all (records, src_string_pool);
|
||||||
free (records.arrayZ);
|
free (records.arrayZ);
|
||||||
|
|
||||||
if (unlikely (c->ran_out_of_room)) return_trace (false);
|
if (unlikely (c->ran_out_of_room)) return_trace (false);
|
||||||
|
|
||||||
assert (this->stringOffset == c->length ());
|
this->stringOffset = c->length ();
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,12 @@ struct hb_serialize_context_t
|
||||||
char *head, *tail;
|
char *head, *tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum whence_t {
|
||||||
|
Head, /* Relative to the current object head (default). */
|
||||||
|
Tail, /* Relative to the current object tail after packed. */
|
||||||
|
Absolute /* Absolute: from the start of the serialize buffer. */
|
||||||
|
};
|
||||||
|
|
||||||
struct object_t : range_t
|
struct object_t : range_t
|
||||||
{
|
{
|
||||||
void fini () { links.fini (); }
|
void fini () { links.fini (); }
|
||||||
|
@ -70,7 +76,9 @@ struct hb_serialize_context_t
|
||||||
struct link_t
|
struct link_t
|
||||||
{
|
{
|
||||||
bool is_wide: 1;
|
bool is_wide: 1;
|
||||||
unsigned position : 31;
|
bool is_signed: 1;
|
||||||
|
unsigned whence: 2;
|
||||||
|
unsigned position: 28;
|
||||||
unsigned bias;
|
unsigned bias;
|
||||||
objidx_t objidx;
|
objidx_t objidx;
|
||||||
};
|
};
|
||||||
|
@ -269,7 +277,9 @@ struct hb_serialize_context_t
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void add_link (T &ofs, objidx_t objidx, const void *base = nullptr)
|
void add_link (T &ofs, objidx_t objidx,
|
||||||
|
const void *base = nullptr,
|
||||||
|
whence_t whence = Head)
|
||||||
{
|
{
|
||||||
static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
|
static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
|
||||||
|
|
||||||
|
@ -279,15 +289,24 @@ struct hb_serialize_context_t
|
||||||
assert (current);
|
assert (current);
|
||||||
assert (current->head <= (const char *) &ofs);
|
assert (current->head <= (const char *) &ofs);
|
||||||
|
|
||||||
if (!base)
|
|
||||||
base = current->head;
|
|
||||||
else
|
|
||||||
assert (current->head <= (const char *) base);
|
|
||||||
|
|
||||||
auto& link = *current->links.push ();
|
auto& link = *current->links.push ();
|
||||||
|
|
||||||
link.is_wide = sizeof (T) == 4;
|
link.is_wide = sizeof (T) == 4;
|
||||||
|
link.is_signed = hb_is_signed (hb_unwrap_type (T));
|
||||||
|
link.whence = (unsigned)whence;
|
||||||
link.position = (const char *) &ofs - current->head;
|
link.position = (const char *) &ofs - current->head;
|
||||||
|
if (whence == Head)
|
||||||
|
{
|
||||||
|
if (base == nullptr)
|
||||||
|
link.bias = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (current->head <= (const char *)base);
|
||||||
link.bias = (const char *) base - current->head;
|
link.bias = (const char *) base - current->head;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
link.bias = 0;
|
||||||
link.objidx = objidx;
|
link.objidx = objidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,20 +321,28 @@ struct hb_serialize_context_t
|
||||||
for (const object_t::link_t &link : parent->links)
|
for (const object_t::link_t &link : parent->links)
|
||||||
{
|
{
|
||||||
const object_t* child = packed[link.objidx];
|
const object_t* child = packed[link.objidx];
|
||||||
assert (link.bias <= (size_t) (parent->tail - parent->head));
|
if (unlikely (!child)) { err_other_error(); return; }
|
||||||
unsigned offset = (child->head - parent->head) - link.bias;
|
unsigned offset;
|
||||||
|
switch ((whence_t)link.whence) {
|
||||||
|
case Head: offset = (child->head - parent->head) - link.bias; break;
|
||||||
|
case Tail: offset = child->head - parent->tail; break;
|
||||||
|
case Absolute: offset = (head - start) + (child->head - tail); break;
|
||||||
|
default: assert (0);
|
||||||
|
}
|
||||||
|
|
||||||
if (link.is_wide)
|
if (link.is_signed)
|
||||||
{
|
{
|
||||||
auto &off = * ((BEInt<uint32_t, 4> *) (parent->head + link.position));
|
if (link.is_wide)
|
||||||
assert (0 == off);
|
assign_offset<int32_t> (parent, link, offset);
|
||||||
check_assign (off, offset);
|
else
|
||||||
|
assign_offset<int16_t> (parent, link, offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto &off = * ((BEInt<uint16_t, 2> *) (parent->head + link.position));
|
if (link.is_wide)
|
||||||
assert (0 == off);
|
assign_offset<uint32_t> (parent, link, offset);
|
||||||
check_assign (off, offset);
|
else
|
||||||
|
assign_offset<uint16_t> (parent, link, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,6 +483,15 @@ struct hb_serialize_context_t
|
||||||
(char *) b.arrayZ, free);
|
(char *) b.arrayZ, free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset)
|
||||||
|
{
|
||||||
|
auto &off = * ((BEInt<T, sizeof (T)> *) (parent->head + link.position));
|
||||||
|
assert (0 == off);
|
||||||
|
check_assign (off, offset);
|
||||||
|
}
|
||||||
|
|
||||||
public: /* TODO Make private. */
|
public: /* TODO Make private. */
|
||||||
char *start, *head, *tail, *end;
|
char *start, *head, *tail, *end;
|
||||||
unsigned int debug_depth;
|
unsigned int debug_depth;
|
||||||
|
|
Loading…
Reference in New Issue