diff options
Diffstat (limited to 'src/hb-ot-name.cc')
-rw-r--r-- | src/hb-ot-name.cc | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 6adf1e8fb..c35ac5b3d 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -64,6 +64,52 @@ hb_ot_name_list_names (hb_face_t *face, return (const hb_ot_name_entry_t *) name.names; } + +template <typename in_utf_t, typename out_utf_t> +static 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; +} + template <typename utf_t> static inline unsigned int hb_ot_name_get_utf (hb_face_t *face, @@ -84,10 +130,10 @@ hb_ot_name_get_utf (hb_face_t *face, hb_bytes_t bytes = name.get_name (idx); if (width == 2) /* UTF16-BE */ - return OT::hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text); + return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (bytes, text_size, text); if (width == 1) /* ASCII */ - return OT::hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text); + return hb_ot_name_convert_utf<hb_ascii_t, utf_t> (bytes, text_size, text); } if (text_size) @@ -181,4 +227,5 @@ hb_ot_name_get_utf32 (hb_face_t *face, return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text); } + #endif |