summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_shaper.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 1ce374c..85dbd4a 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -97,10 +97,10 @@ void ass_shaper_info(ASS_Library *lib)
}
/**
- * \brief grow arrays, if needed
+ * \brief grow per-codepoint arrays, if needed
* \param new_size requested size
*/
-static bool check_allocations(ASS_Shaper *shaper, size_t new_size, size_t n_pars)
+static bool check_codepoint_allocations(ASS_Shaper *shaper, size_t new_size)
{
if (new_size > shaper->n_codepoints) {
if (!ASS_REALLOC_ARRAY(shaper->ctypes, new_size) ||
@@ -112,6 +112,15 @@ static bool check_allocations(ASS_Shaper *shaper, size_t new_size, size_t n_pars
return false;
shaper->n_codepoints = new_size;
}
+ return true;
+}
+
+/**
+ * \brief grow per-bidi-paragraph arrays, if needed
+ * \param n_pars requested size
+ */
+static bool check_par_allocations(ASS_Shaper *shaper, size_t n_pars)
+{
if (shaper->whole_text_layout && n_pars > shaper->n_pars) {
if (!ASS_REALLOC_ARRAY(shaper->pbase_dir, n_pars))
return false;
@@ -968,12 +977,7 @@ bool ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info)
GlyphInfo *glyphs = text_info->glyphs;
shaper->event_text = text_info->event_text;
- int n_pars = 1;
- for (i = 0; i < text_info->length - 1; i++)
- if (glyphs[i].symbol == '\n')
- n_pars++;
-
- if (!check_allocations(shaper, text_info->length, n_pars))
+ if (!check_codepoint_allocations(shaper, text_info->length))
return false;
for (i = 0; i < text_info->length; i++)
@@ -982,6 +986,14 @@ bool ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info)
fribidi_get_bidi_types(shaper->event_text,
text_info->length, shaper->ctypes);
+ int n_pars = 1;
+ for (i = 0; i < text_info->length - 1; i++)
+ if (shaper->ctypes[i] == FRIBIDI_TYPE_BS)
+ n_pars++;
+
+ if (!check_par_allocations(shaper, n_pars))
+ return false;
+
#ifdef USE_FRIBIDI_EX_API
if (shaper->bidi_brackets) {
fribidi_get_bracket_types(shaper->event_text,
@@ -994,7 +1006,8 @@ bool ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info)
pdir = shaper->pbase_dir;
for (i = 0; i < text_info->length; i++) {
// embedding levels should be calculated paragraph by paragraph
- if (glyphs[i].symbol == '\n' || i == text_info->length - 1 ||
+ if (i == text_info->length - 1 ||
+ shaper->ctypes[i] == FRIBIDI_TYPE_BS ||
(!shaper->whole_text_layout &&
(glyphs[i + 1].starts_new_run || glyphs[i].hspacing))) {
dir = shaper->base_direction;
@@ -1091,7 +1104,11 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info)
shaper->pbase_dir : &shaper->base_direction;
GlyphInfo *glyphs = text_info->glyphs;
for (i = 0; i < text_info->length; i++) {
+ // Bidi "paragraph separators" may occur between line breaks:
+ // U+001C..1E even with ASS_FEATURE_WRAP_UNICODE,
+ // or U+000D, U+0085, U+2029 only without it
if (i == text_info->length - 1 || glyphs[i + 1].linebreak ||
+ shaper->ctypes[i] == FRIBIDI_TYPE_BS ||
(!shaper->whole_text_layout &&
(glyphs[i + 1].starts_new_run || glyphs[i].hspacing))) {
ret = fribidi_reorder_line(0,
@@ -1102,7 +1119,7 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info)
return NULL;
last_break = i + 1;
- if (shaper->whole_text_layout && glyphs[i].symbol == '\n')
+ if (shaper->whole_text_layout && shaper->ctypes[i] == FRIBIDI_TYPE_BS)
pdir++;
}
}