diff options
author | wm4 <wm4@nowhere> | 2015-09-20 19:21:37 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-09-20 19:32:36 +0200 |
commit | 7dc433e5a65a11ea6b1b216c217a24cbc7c97050 (patch) | |
tree | e6f3881e2e1e36d872b0b98fa9d2389ed9c29184 | |
parent | 32b2424fe9bba9602c8344fcc242ad58ea525cb3 (diff) | |
download | libass-7dc433e5a65a11ea6b1b216c217a24cbc7c97050.tar.bz2 libass-7dc433e5a65a11ea6b1b216c217a24cbc7c97050.tar.xz |
fontselect: make iconv optional again
It was needed for UTF16BE -> UTF8 only, which is trivial to implement.
-rw-r--r-- | libass/ass_fontselect.c | 24 | ||||
-rw-r--r-- | libass/ass_utils.c | 39 | ||||
-rw-r--r-- | libass/ass_utils.h | 1 |
3 files changed, 42 insertions, 22 deletions
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c index e75eb1f..b437000 100644 --- a/libass/ass_fontselect.c +++ b/libass/ass_fontselect.c @@ -34,7 +34,6 @@ #include FT_FREETYPE_H #include FT_SFNT_NAMES_H #include FT_TRUETYPE_IDS_H -#include <iconv.h> #include "ass_utils.h" #include "ass.h" @@ -720,18 +719,11 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) int slant, weight; char *fullnames[MAX_FULLNAME]; char *families[MAX_FULLNAME]; - iconv_t utf16to8; // we're only interested in outlines if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) return 0; - // scan font names - utf16to8 = iconv_open("UTF-8", "UTF-16BE"); - - if (utf16to8 == (iconv_t)-1) - goto error; - for (i = 0; i < num_names; i++) { FT_SfntName name; @@ -742,15 +734,8 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) (name.name_id == TT_NAME_ID_FULL_NAME || name.name_id == TT_NAME_ID_FONT_FAMILY)) { char buf[1024]; - char *bufptr = buf; - size_t inbytes = name.string_len; - size_t outbytes = 1024; - - if (iconv(utf16to8, (char**)&name.string, &inbytes, &bufptr, - &outbytes) == (size_t)-1) - continue; - - *bufptr = '\0'; + ass_utf16be_to_utf8(buf, sizeof(buf), (uint8_t *)name.string, + name.string_len); if (name.name_id == TT_NAME_ID_FULL_NAME) { fullnames[num_fullname] = strdup_trimmed(buf); @@ -768,8 +753,6 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) } } - iconv_close(utf16to8); - utf16to8 = (iconv_t)-1; // check if we got a valid family - if not use whatever FreeType gives us if (num_family == 0 && face->family_name) { @@ -810,9 +793,6 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) return 0; error: - if (utf16to8 != (iconv_t)-1) - iconv_close(utf16to8); - for (i = 0; i < num_family; i++) free(families[i]); diff --git a/libass/ass_utils.c b/libass/ass_utils.c index 9c9155b..91b1873 100644 --- a/libass/ass_utils.c +++ b/libass/ass_utils.c @@ -418,6 +418,45 @@ unsigned ass_utf8_put_char(char *dest, uint32_t ch) } /** + * \brief Parse UTF-16 and return the code point of the sequence starting at src. + * \param src pointer to a pointer to the start of the UTF-16 data + * (will be set to the start of the next code point) + * \return the code point + */ +static uint32_t ass_read_utf16be(uint8_t **src) +{ + uint32_t cp = ((*src)[0] << 8) | (*src)[1]; + *src += 2; + + if (cp >= 0xD800 && cp <= 0xDBFF) { + uint32_t cp2 = ((*src)[0] << 8) | (*src)[1]; + *src += 2; + + cp = 0x10000 + ((cp - 0xD800) << 10) + (cp2 - 0xDC00); + } + + return cp; +} + +void ass_utf16be_to_utf8(char *dst, size_t dst_size, uint8_t *src, size_t src_size) +{ + uint8_t *end = src + src_size; + + if (!dst_size) + return; + dst[0] = '\0'; + + while (src < end) { + uint32_t cp = ass_read_utf16be(&src); + if (dst_size < 5) + break; + unsigned s = ass_utf8_put_char(dst, cp); + dst += s; + dst_size -= s; + } +} + +/** * \brief find style by name * \param track track * \param name style name diff --git a/libass/ass_utils.h b/libass/ass_utils.h index 8295d4e..8938c30 100644 --- a/libass/ass_utils.h +++ b/libass/ass_utils.h @@ -96,6 +96,7 @@ char parse_bool(char *str); int parse_ycbcr_matrix(char *str); unsigned ass_utf8_get_char(char **str); unsigned ass_utf8_put_char(char *dest, uint32_t ch); +void ass_utf16be_to_utf8(char *dst, size_t dst_size, uint8_t *src, size_t src_size); void ass_msg(ASS_Library *priv, int lvl, const char *fmt, ...); int lookup_style(ASS_Track *track, char *name); ASS_Style *lookup_style_strict(ASS_Track *track, char *name, size_t len); |