|
|
|
@ -30,10 +30,55 @@ |
|
|
|
|
#include "hb-open-type.hh" |
|
|
|
|
#include "hb-ot-name-language.hh" |
|
|
|
|
#include "hb-aat-layout.hh" |
|
|
|
|
#include "hb-utf.hh" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace OT { |
|
|
|
|
|
|
|
|
|
template <typename in_utf_t, typename out_utf_t> |
|
|
|
|
inline unsigned int |
|
|
|
|
hb_ot_name_convert_utf (hb_bytes_t bytes, |
|
|
|
|
unsigned int *text_size /* IN/OUT */, |
|
|
|
|
typename out_utf_t::codepoint_t *text /* OUT */) |
|
|
|
|
{ |
|
|
|
|
unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t); |
|
|
|
|
const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ; |
|
|
|
|
const typename in_utf_t::codepoint_t *src_end = src + src_len; |
|
|
|
|
|
|
|
|
|
typename out_utf_t::codepoint_t *dst = text; |
|
|
|
|
|
|
|
|
|
hb_codepoint_t unicode; |
|
|
|
|
const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; |
|
|
|
|
|
|
|
|
|
if (text_size && *text_size) |
|
|
|
|
{ |
|
|
|
|
(*text_size)--; /* Same room for NUL-termination. */ |
|
|
|
|
const typename out_utf_t::codepoint_t *dst_end = text + *text_size; |
|
|
|
|
|
|
|
|
|
while (src < src_end && dst < dst_end) |
|
|
|
|
{ |
|
|
|
|
const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement); |
|
|
|
|
typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode); |
|
|
|
|
if (dst_next == dst) |
|
|
|
|
break; /* Out-of-room. */ |
|
|
|
|
|
|
|
|
|
dst = dst_next; |
|
|
|
|
src = src_next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*text_size = dst - text; |
|
|
|
|
*dst = 0; /* NUL-terminate. */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Accumulate length of rest. */ |
|
|
|
|
unsigned int dst_len = dst - text; |
|
|
|
|
while (src < src_end) |
|
|
|
|
{ |
|
|
|
|
src = in_utf_t::next (src, src_end, &unicode, replacement); |
|
|
|
|
dst_len += out_utf_t::encode_len (unicode); |
|
|
|
|
} |
|
|
|
|
return dst_len; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define entry_score var.u16[0] |
|
|
|
|
#define entry_index var.u16[1] |
|
|
|
@ -97,12 +142,39 @@ struct NameRecord |
|
|
|
|
return UNSUPPORTED; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NameRecord* copy (hb_serialize_context_t *c, const void *base) const |
|
|
|
|
NameRecord* copy (hb_serialize_context_t *c, const void *base, |
|
|
|
|
const hb_hashmap_t<unsigned, hb_bytes_t> *name_table_overrides) const |
|
|
|
|
{ |
|
|
|
|
TRACE_SERIALIZE (this); |
|
|
|
|
auto snap = c->snapshot (); |
|
|
|
|
auto *out = c->embed (this); |
|
|
|
|
if (unlikely (!out)) return_trace (nullptr); |
|
|
|
|
out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length); |
|
|
|
|
if (name_table_overrides->has (nameID)) { |
|
|
|
|
hb_bytes_t name_bytes = name_table_overrides->get (nameID); |
|
|
|
|
char *name_str_utf16_be = (char *) hb_calloc ((name_bytes.length + 1) * 4, 1); |
|
|
|
|
unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (name_bytes, nullptr, |
|
|
|
|
(hb_utf16_be_t::codepoint_t *) name_str_utf16_be); |
|
|
|
|
|
|
|
|
|
text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
|
|
|
|
|
hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (name_bytes, &text_size, |
|
|
|
|
(hb_utf16_be_t::codepoint_t *) name_str_utf16_be); |
|
|
|
|
|
|
|
|
|
unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; |
|
|
|
|
if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) { |
|
|
|
|
c->revert (snap); |
|
|
|
|
hb_free (name_str_utf16_be); |
|
|
|
|
return_trace (nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
hb_bytes_t utf16_be_bytes (name_str_utf16_be, encoded_byte_len); |
|
|
|
|
out->offset = 0; |
|
|
|
|
c->push (); |
|
|
|
|
utf16_be_bytes.copy (c); |
|
|
|
|
c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0); |
|
|
|
|
hb_free (name_str_utf16_be); |
|
|
|
|
} else { |
|
|
|
|
out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length); |
|
|
|
|
} |
|
|
|
|
return_trace (out); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -216,7 +288,8 @@ struct name |
|
|
|
|
hb_requires (hb_is_source_of (Iterator, const NameRecord &))> |
|
|
|
|
bool serialize (hb_serialize_context_t *c, |
|
|
|
|
Iterator it, |
|
|
|
|
const void *src_string_pool) |
|
|
|
|
const void *src_string_pool, |
|
|
|
|
const hb_hashmap_t<unsigned, hb_bytes_t> *name_table_overrides) |
|
|
|
|
{ |
|
|
|
|
TRACE_SERIALIZE (this); |
|
|
|
|
|
|
|
|
@ -238,7 +311,7 @@ struct name |
|
|
|
|
|
|
|
|
|
records.qsort (); |
|
|
|
|
|
|
|
|
|
c->copy_all (records, src_string_pool); |
|
|
|
|
c->copy_all (records, src_string_pool, name_table_overrides); |
|
|
|
|
hb_free (records.arrayZ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -267,7 +340,7 @@ struct name |
|
|
|
|
}) |
|
|
|
|
; |
|
|
|
|
|
|
|
|
|
name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset)); |
|
|
|
|
name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset), c->plan->name_table_overrides); |
|
|
|
|
return_trace (name_prime->count); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|