From 66dba8dd21bbf81b25b26e2556c404006f80a43c Mon Sep 17 00:00:00 2001 From: Oleg Oshmyan Date: Tue, 14 Jul 2020 00:38:43 +0300 Subject: Disable bidi bracket matching unless enabled via ASS_Feature Bracket matching is incompatible with VSFilter (even on modern Windows), so disable it by default. But as it's generally a good thing (and 100% more compliant with current Unicode), keep it available as an ASS_Feature. It can be toggled individually or enabled as part of the catch-all ASS_FEATURE_INCOMPATIBLE_EXTENSIONS feature. If libass is compiled against FriBidi older than 1.0, bracket matching is impossible. Signal this at runtime by failing to recognize the ASS_FEATURE_BIDI_BRACKETS feature. This way, clients who want to use bracket matching can set the feature without any compile-time checks for FriBidi and can be freely linked against libass that is itself compiled against any version of FriBidi; and yet they can detect at runtime whether the feature is actually enabled. Fixes https://github.com/libass/libass/issues/374. --- libass/ass_shaper.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'libass/ass_shaper.c') diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c index ab94f10..fc12974 100644 --- a/libass/ass_shaper.c +++ b/libass/ass_shaper.c @@ -39,10 +39,6 @@ enum { #define NUM_FEATURES 5 #endif -#if FRIBIDI_MAJOR_VERSION >= 1 -#define USE_FRIBIDI_EX_API -#endif - struct ass_shaper { ASS_ShapingLevel shaping_level; @@ -50,9 +46,6 @@ struct ass_shaper { int n_glyphs; FriBidiChar *event_text; FriBidiCharType *ctypes; -#ifdef USE_FRIBIDI_EX_API - FriBidiBracketType *btypes; -#endif FriBidiLevel *emblevels; FriBidiStrIndex *cmap; FriBidiParType base_direction; @@ -66,6 +59,11 @@ struct ass_shaper { // Glyph metrics cache, to speed up shaping Cache *metrics_cache; #endif + +#ifdef USE_FRIBIDI_EX_API + FriBidiBracketType *btypes; + bool bidi_brackets; +#endif }; #ifdef CONFIG_HARFBUZZ @@ -105,7 +103,7 @@ static bool check_allocations(ASS_Shaper *shaper, size_t new_size) if (!ASS_REALLOC_ARRAY(shaper->event_text, new_size) || !ASS_REALLOC_ARRAY(shaper->ctypes, new_size) || #ifdef USE_FRIBIDI_EX_API - !ASS_REALLOC_ARRAY(shaper->btypes, new_size) || + (shaper->bidi_brackets && !ASS_REALLOC_ARRAY(shaper->btypes, new_size)) || #endif !ASS_REALLOC_ARRAY(shaper->emblevels, new_size) || !ASS_REALLOC_ARRAY(shaper->cmap, new_size)) @@ -860,6 +858,13 @@ void ass_shaper_set_level(ASS_Shaper *shaper, ASS_ShapingLevel level) shaper->shaping_level = level; } +#ifdef USE_FRIBIDI_EX_API +void ass_shaper_set_bidi_brackets(ASS_Shaper *shaper, bool match_brackets) +{ + shaper->bidi_brackets = match_brackets; +} +#endif + /** * \brief Remove all zero-width invisible characters from the text. * \param text_info text @@ -907,11 +912,15 @@ int ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) fribidi_get_bidi_types(shaper->event_text + last_break, i - last_break + 1, shaper->ctypes + last_break); #ifdef USE_FRIBIDI_EX_API - fribidi_get_bracket_types(shaper->event_text + last_break, - i - last_break + 1, shaper->ctypes + last_break, - shaper->btypes + last_break); + FriBidiBracketType *btypes = NULL; + if (shaper->bidi_brackets) { + btypes = shaper->btypes + last_break; + fribidi_get_bracket_types(shaper->event_text + last_break, + i - last_break + 1, shaper->ctypes + last_break, + btypes); + } ret = fribidi_get_par_embedding_levels_ex( - shaper->ctypes + last_break, shaper->btypes + last_break, + shaper->ctypes + last_break, btypes, i - last_break + 1, &dir, shaper->emblevels + last_break); #else ret = fribidi_get_par_embedding_levels(shaper->ctypes + last_break, -- cgit v1.2.3