summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorApache553 <Apache553@outlook.com>2022-01-16 16:52:40 +0800
committerApache553 <Apache553@outlook.com>2022-01-30 01:58:55 +0800
commit88cf01a448b1a14c8364294946f349af074c1969 (patch)
treec968de91899d4e3e4c774e83127e1027c95e8ec0
parentf57084876060662d47f377e5735913215c04b329 (diff)
downloadlibass-88cf01a448b1a14c8364294946f349af074c1969.tar.bz2
libass-88cf01a448b1a14c8364294946f349af074c1969.tar.xz
font: handle conversion failure better
If a conversion fails for a non-Unicode font, let font fallback happen instead of displaying bogus glyphs.
-rw-r--r--libass/ass_font.c28
-rw-r--r--libass/ass_shaper.c12
2 files changed, 27 insertions, 13 deletions
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 3f44a1f..1496924 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -82,7 +82,7 @@ static uint32_t convert_unicode_to_mb(FT_Encoding encoding, uint32_t codepoint)
codepage = 1361;
break;
default:
- return codepoint;
+ return 0;
}
WCHAR input_buffer[2];
@@ -105,7 +105,7 @@ static uint32_t convert_unicode_to_mb(FT_Encoding encoding, uint32_t codepoint)
int output_length = WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, input_buffer, inbuf_size,
output_buffer, sizeof(output_buffer), NULL, &conversion_fail);
if (output_length == 0 || conversion_fail)
- return codepoint;
+ return 0;
return pack_mbcs_bytes(output_buffer, output_length);
}
@@ -137,7 +137,7 @@ static uint32_t convert_unicode_to_mb(FT_Encoding encoding, uint32_t codepoint)
encoding_list = (EncodingList) {{"CP1361", "JOHAB", NULL}};
break;
default:
- return codepoint;
+ return 0;
}
// open iconv context
@@ -149,18 +149,18 @@ static uint32_t convert_unicode_to_mb(FT_Encoding encoding, uint32_t codepoint)
++encoding_str;
}
if (cd == (iconv_t) -1)
- return codepoint;
+ return 0;
char input_buffer[4];
char output_buffer[2]; // MS-flavour encodings only need 2 bytes
uint32_t result = codepoint;
- // convert input codepoint to little endian uint32_t bytearray
+ // convert input codepoint to little endian uint32_t bytearray,
+ // result becomes 0 after the loop finishes
for (int i = 0; i < 4; ++i) {
input_buffer[i] = result & 0xFF;
result >>= 8;
}
- result = codepoint;
// do actual convert, only reversible converts are valid, since we are converting unicode to something else
size_t inbuf_size = sizeof(input_buffer);
@@ -182,7 +182,8 @@ clean:
#else
static uint32_t convert_unicode_to_mb(FT_Encoding encoding, uint32_t codepoint) {
// just a stub
- return codepoint;
+ // we can't handle this cmap, fallback
+ return 0;
}
#endif
@@ -578,7 +579,9 @@ int ass_font_get_index(ASS_FontSelector *fontsel, ASS_Font *font,
for (i = 0; i < font->n_faces && index == 0; ++i) {
face = font->faces[i];
- index = FT_Get_Char_Index(face, ass_font_index_magic(face, symbol));
+ index = ass_font_index_magic(face, symbol);
+ if (index)
+ index = FT_Get_Char_Index(face, index);
if (index)
*face_index = i;
}
@@ -592,14 +595,19 @@ int ass_font_get_index(ASS_FontSelector *fontsel, ASS_Font *font,
face_idx = *face_index = add_face(fontsel, font, symbol);
if (face_idx >= 0) {
face = font->faces[face_idx];
- index = FT_Get_Char_Index(face, ass_font_index_magic(face, symbol));
+ index = ass_font_index_magic(face, symbol);
+ if (index)
+ index = FT_Get_Char_Index(face, index);
if (index == 0 && face->num_charmaps > 0) {
int i;
ass_msg(font->library, MSGL_WARN,
"Glyph 0x%X not found, broken font? Trying all charmaps", symbol);
for (i = 0; i < face->num_charmaps; i++) {
FT_Set_Charmap(face, face->charmaps[i]);
- if ((index = FT_Get_Char_Index(face, ass_font_index_magic(face, symbol))) != 0) break;
+ index = ass_font_index_magic(face, symbol);
+ if (index)
+ index = FT_Get_Char_Index(face, index);
+ if (index) break;
}
}
if (index == 0) {
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index e406fd1..f95dd58 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -283,7 +283,9 @@ get_glyph_nominal(hb_font_t *font, void *font_data, hb_codepoint_t unicode,
FT_Face face = font_data;
struct ass_shaper_metrics_data *metrics_priv = user_data;
- *glyph = FT_Get_Char_Index(face, ass_font_index_magic(face, unicode));
+ *glyph = ass_font_index_magic(face, unicode);
+ if (*glyph)
+ *glyph = FT_Get_Char_Index(face, *glyph);
if (!*glyph)
return false;
@@ -300,7 +302,9 @@ get_glyph_variation(hb_font_t *font, void *font_data, hb_codepoint_t unicode,
FT_Face face = font_data;
struct ass_shaper_metrics_data *metrics_priv = user_data;
- *glyph = FT_Face_GetCharVariantIndex(face, ass_font_index_magic(face, unicode), variation);
+ *glyph = ass_font_index_magic(face, unicode);
+ if (*glyph)
+ *glyph = FT_Face_GetCharVariantIndex(face, *glyph, variation);
if (!*glyph)
return false;
@@ -794,7 +798,9 @@ static void shape_fribidi(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
GlyphInfo *info = glyphs + i;
FT_Face face = info->font->faces[info->face_index];
info->symbol = shaper->event_text[i];
- info->glyph_index = FT_Get_Char_Index(face, ass_font_index_magic(face, shaper->event_text[i]));
+ info->glyph_index = ass_font_index_magic(face, shaper->event_text[i]);
+ if (info->glyph_index)
+ info->glyph_index = FT_Get_Char_Index(face, info->glyph_index);
}
free(joins);