summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-09-20 19:21:37 +0200
committerwm4 <wm4@nowhere>2015-09-21 21:47:34 +0200
commit3e8ea9421204b51a819d983ee1d924621259043c (patch)
treecdef54d645798fbc2430b966e26a26f7172938b2 /libass
parent32b2424fe9bba9602c8344fcc242ad58ea525cb3 (diff)
downloadlibass-3e8ea9421204b51a819d983ee1d924621259043c.tar.bz2
libass-3e8ea9421204b51a819d983ee1d924621259043c.tar.xz
fontselect: make iconv optional again
It was needed for UTF16BE -> UTF8 only, which is trivial to implement.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_fontselect.c24
-rw-r--r--libass/ass_utils.c58
-rw-r--r--libass/ass_utils.h1
3 files changed, 61 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..1614a32 100644
--- a/libass/ass_utils.c
+++ b/libass/ass_utils.c
@@ -418,6 +418,64 @@ 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, size_t bytes)
+{
+ if (bytes < 2)
+ goto too_short;
+
+ uint32_t cp = ((*src)[0] << 8) | (*src)[1];
+ *src += 2;
+ bytes -= 2;
+
+ if (cp >= 0xD800 && cp <= 0xDBFF) {
+ if (bytes < 2)
+ goto too_short;
+
+ uint32_t cp2 = ((*src)[0] << 8) | (*src)[1];
+
+ if (cp2 < 0xDC00 || cp2 > 0xDFFF)
+ return 0xFFFD;
+
+ *src += 2;
+
+ cp = 0x10000 + ((cp - 0xD800) << 10) + (cp2 - 0xDC00);
+ }
+
+ if (cp >= 0xDC00 && cp <= 0xDFFF)
+ return 0xFFFD;
+
+ return cp;
+
+too_short:
+ *src += bytes;
+ return 0xFFFD;
+}
+
+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;
+
+ while (src < end) {
+ uint32_t cp = ass_read_utf16be(&src, end - src);
+ if (dst_size < 5)
+ break;
+ unsigned s = ass_utf8_put_char(dst, cp);
+ dst += s;
+ dst_size -= s;
+ }
+
+ *dst = '\0';
+}
+
+/**
* \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);