summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2020-07-14 00:38:43 +0300
committerOleg Oshmyan <chortos@inbox.lv>2020-07-14 20:14:44 +0300
commit66dba8dd21bbf81b25b26e2556c404006f80a43c (patch)
tree28080a0ab2a4110e0cfa7bc8a8e909391356b336 /libass
parentc1aff3a86e00e99e750057a956f27564120934cb (diff)
downloadlibass-66dba8dd21bbf81b25b26e2556c404006f80a43c.tar.bz2
libass-66dba8dd21bbf81b25b26e2556c404006f80a43c.tar.xz
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.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass.c7
-rw-r--r--libass/ass.h15
-rw-r--r--libass/ass_priv.h9
-rw-r--r--libass/ass_render.c5
-rw-r--r--libass/ass_shaper.c33
-rw-r--r--libass/ass_shaper.h7
6 files changed, 60 insertions, 16 deletions
diff --git a/libass/ass.c b/libass/ass.c
index 13cfea5..811a9a7 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -36,6 +36,7 @@
#include "ass_utils.h"
#include "ass_library.h"
#include "ass_priv.h"
+#include "ass_shaper.h"
#include "ass_string.h"
#define ass_atof(STR) (ass_strtod((STR),NULL))
@@ -1468,7 +1469,11 @@ int ass_track_set_feature(ASS_Track *track, ASS_Feature feature, int enable)
{
switch (feature) {
case ASS_FEATURE_INCOMPATIBLE_EXTENSIONS:
- track->parser_priv->enable_extensions = !!enable;
+ //-fallthrough
+#ifdef USE_FRIBIDI_EX_API
+ case ASS_FEATURE_BIDI_BRACKETS:
+ track->parser_priv->bidi_brackets = !!enable;
+#endif
return 0;
default:
return -1;
diff --git a/libass/ass.h b/libass/ass.h
index 35aeeb7..db67ed2 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -24,7 +24,7 @@
#include <stdarg.h>
#include "ass_types.h"
-#define LIBASS_VERSION 0x01400001
+#define LIBASS_VERSION 0x01400002
#ifdef __cplusplus
extern "C" {
@@ -209,6 +209,19 @@ typedef enum {
*/
ASS_FEATURE_INCOMPATIBLE_EXTENSIONS,
+ /**
+ * Match bracket pairs in bidirectional text according to the revised
+ * Unicode Bidirectional Algorithm introduced in Unicode 6.3.
+ * This is incompatible with VSFilter and disabled by default.
+ *
+ * (Directional isolates, also introduced in Unicode 6.3,
+ * are unconditionally processed when FriBidi is new enough.)
+ *
+ * This feature may be unavailable at runtime (ass_track_set_feature
+ * may return -1) if libass was compiled against old FriBidi.
+ */
+ ASS_FEATURE_BIDI_BRACKETS,
+
// New enum values can be added here in new ABI-compatible library releases.
} ASS_Feature;
diff --git a/libass/ass_priv.h b/libass/ass_priv.h
index 3ee2b45..98b2711 100644
--- a/libass/ass_priv.h
+++ b/libass/ass_priv.h
@@ -19,8 +19,11 @@
#ifndef LIBASS_PRIV_H
#define LIBASS_PRIV_H
+#include <stdbool.h>
#include <stdint.h>
+#include "ass_shaper.h"
+
typedef enum {
PST_UNKNOWN = 0,
PST_INFO,
@@ -55,10 +58,12 @@ struct parser_priv {
int read_order_elems; // size in uint32_t units of read_order_bitmap
int check_readorder;
- int enable_extensions;
-
// tracks [Script Info] headers set by the script
uint32_t header_flags;
+
+#ifdef USE_FRIBIDI_EX_API
+ bool bidi_brackets;
+#endif
};
#endif /* LIBASS_PRIV_H */
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 7bc9554..28b6461 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -27,6 +27,7 @@
#include "ass_outline.h"
#include "ass_render.h"
#include "ass_parse.h"
+#include "ass_priv.h"
#include "ass_shaper.h"
#define MAX_GLYPHS_INITIAL 1024
@@ -2833,6 +2834,10 @@ ass_start_frame(ASS_Renderer *render_priv, ASS_Track *track,
ass_shaper_set_kerning(render_priv->shaper, track->Kerning);
ass_shaper_set_language(render_priv->shaper, track->Language);
ass_shaper_set_level(render_priv->shaper, render_priv->settings.shaper);
+#ifdef USE_FRIBIDI_EX_API
+ ass_shaper_set_bidi_brackets(render_priv->shaper,
+ track->parser_priv->bidi_brackets);
+#endif
// PAR correction
double par = render_priv->settings.par;
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,
diff --git a/libass/ass_shaper.h b/libass/ass_shaper.h
index d12870f..9ff96e7 100644
--- a/libass/ass_shaper.h
+++ b/libass/ass_shaper.h
@@ -25,6 +25,10 @@ typedef struct ass_shaper ASS_Shaper;
#include <stdbool.h>
#include "ass_render.h"
+#if FRIBIDI_MAJOR_VERSION >= 1
+#define USE_FRIBIDI_EX_API
+#endif
+
void ass_shaper_info(ASS_Library *lib);
ASS_Shaper *ass_shaper_new(void);
void ass_shaper_free(ASS_Shaper *shaper);
@@ -35,6 +39,9 @@ void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir);
void ass_shaper_set_language(ASS_Shaper *shaper, const char *code);
void ass_shaper_set_level(ASS_Shaper *shaper, ASS_ShapingLevel level);
+#ifdef USE_FRIBIDI_EX_API
+void ass_shaper_set_bidi_brackets(ASS_Shaper *shaper, bool match_brackets);
+#endif
int ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info);
void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info);
FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info);