diff options
Diffstat (limited to 'libass/ass_shaper.c')
-rw-r--r-- | libass/ass_shaper.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c index f95dd58..b05a051 100644 --- a/libass/ass_shaper.c +++ b/libass/ass_shaper.c @@ -39,6 +39,12 @@ enum { }; #define NUM_FEATURES 5 +enum { + WHOLE_TEXT_LAYOUT_OFF, + WHOLE_TEXT_LAYOUT_IMPLICIT, + WHOLE_TEXT_LAYOUT_EXPLICIT, +}; + struct ass_shaper { ASS_ShapingLevel shaping_level; @@ -62,6 +68,8 @@ struct ass_shaper { FriBidiBracketType *btypes; bool bidi_brackets; #endif + + char whole_text_layout; }; struct ass_shaper_metrics_data { @@ -895,6 +903,10 @@ void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv, void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir) { shaper->base_direction = dir; + + if (shaper->whole_text_layout != WHOLE_TEXT_LAYOUT_EXPLICIT) + shaper->whole_text_layout = dir == FRIBIDI_PAR_ON ? + WHOLE_TEXT_LAYOUT_IMPLICIT : WHOLE_TEXT_LAYOUT_OFF; } /** @@ -929,6 +941,14 @@ void ass_shaper_set_bidi_brackets(ASS_Shaper *shaper, bool match_brackets) } #endif +void ass_shaper_set_whole_text_layout(ASS_Shaper *shaper, bool enable) +{ + shaper->whole_text_layout = enable ? + WHOLE_TEXT_LAYOUT_EXPLICIT : + shaper->base_direction == FRIBIDI_PAR_ON ? + WHOLE_TEXT_LAYOUT_IMPLICIT : WHOLE_TEXT_LAYOUT_OFF; +} + /** * \brief Shape an event's text. Calculates directional runs and shapes them. * \param text_info event's text @@ -948,7 +968,8 @@ bool ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) for (i = 0; i < text_info->length; i++) { shaper->event_text[i] = glyphs[i].symbol; // embedding levels should be calculated paragraph by paragraph - if (glyphs[i].symbol == '\n' || i == text_info->length - 1) { + if (glyphs[i].symbol == '\n' || i == text_info->length - 1 || + (!shaper->whole_text_layout && glyphs[i + 1].starts_new_run)) { dir = shaper->base_direction; fribidi_get_bidi_types(shaper->event_text + last_break, i - last_break + 1, shaper->ctypes + last_break); @@ -1041,17 +1062,23 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info) for (i = 0; i < text_info->length; i++) shaper->cmap[i] = i; - // Create reorder map line-by-line - for (i = 0; i < text_info->n_lines; i++) { - LineInfo *line = text_info->lines + i; - FriBidiParType dir = FRIBIDI_PAR_ON; + // Create reorder map line-by-line or run-by-run + int last_break = 0; + GlyphInfo *glyphs = text_info->glyphs; + for (i = 0; i < text_info->length; i++) { + if (i == text_info->length - 1 || glyphs[i + 1].linebreak || + (!shaper->whole_text_layout && glyphs[i + 1].starts_new_run)) { + FriBidiParType dir = FRIBIDI_PAR_ON; + + ret = fribidi_reorder_line(0, + shaper->ctypes, i - last_break + 1, last_break, dir, + shaper->emblevels, NULL, + shaper->cmap); + if (ret == 0) + return NULL; - ret = fribidi_reorder_line(0, - shaper->ctypes + line->offset, line->len, 0, dir, - shaper->emblevels + line->offset, NULL, - shaper->cmap + line->offset); - if (ret == 0) - return NULL; + last_break = i + 1; + } } return shaper->cmap; |