diff options
author | Oneric <oneric@oneric.stub> | 2021-03-19 00:34:33 +0100 |
---|---|---|
committer | Oneric <oneric@oneric.stub> | 2022-08-19 19:03:38 +0200 |
commit | 169862065a70bedd202bce3c2f92f0e880f70029 (patch) | |
tree | b77e92dba687abd60eaa3fc4fbb01d2c80f8b95d | |
parent | c610332853b6581802f07229101c0889ed731ee5 (diff) | |
download | libass-169862065a70bedd202bce3c2f92f0e880f70029.tar.bz2 libass-169862065a70bedd202bce3c2f92f0e880f70029.tar.xz |
Move event_text to text_info
And fix reallocation; previously when encountering a line
longer than two times the current max_glyphs, the code would
always underallocate and go to failure handling, even if enough
space could have been allocated.
Prepares Unicode Line Breaking.
-rw-r--r-- | libass/ass_render.c | 8 | ||||
-rw-r--r-- | libass/ass_render.h | 2 | ||||
-rw-r--r-- | libass/ass_shaper.c | 7 |
3 files changed, 11 insertions, 6 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c index c0451a3..5fac76b 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -107,6 +107,7 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library) priv->text_info.n_bitmaps = 0; priv->text_info.combined_bitmaps = calloc(MAX_BITMAPS_INITIAL, sizeof(CombinedBitmapInfo)); priv->text_info.glyphs = calloc(MAX_GLYPHS_INITIAL, sizeof(GlyphInfo)); + priv->text_info.event_text = calloc(MAX_GLYPHS_INITIAL, sizeof(FriBidiChar)); priv->text_info.lines = calloc(MAX_LINES_INITIAL, sizeof(LineInfo)); if (!priv->text_info.combined_bitmaps || !priv->text_info.glyphs || !priv->text_info.lines) goto fail; @@ -153,6 +154,7 @@ void ass_renderer_done(ASS_Renderer *render_priv) FT_Done_FreeType(render_priv->ftlibrary); free(render_priv->eimg); free(render_priv->text_info.glyphs); + free(render_priv->text_info.event_text); free(render_priv->text_info.lines); free(render_priv->text_info.combined_bitmaps); @@ -1967,10 +1969,12 @@ static bool parse_events(ASS_Renderer *render_priv, ASS_Event *event) if (text_info->length >= text_info->max_glyphs) { // Raise maximum number of glyphs - int new_max = 2 * FFMIN(text_info->max_glyphs, INT_MAX / 2); + int new_max = 2 * FFMIN(FFMAX(text_info->max_glyphs, text_info->length / 2 + 1), + INT_MAX / 2); if (text_info->length >= new_max) goto fail; - if (!ASS_REALLOC_ARRAY(text_info->glyphs, new_max)) + if (!ASS_REALLOC_ARRAY(text_info->glyphs, new_max) || + !ASS_REALLOC_ARRAY(text_info->event_text, new_max)) goto fail; text_info->max_glyphs = new_max; } diff --git a/libass/ass_render.h b/libass/ass_render.h index 116722b..58b6aa2 100644 --- a/libass/ass_render.h +++ b/libass/ass_render.h @@ -22,6 +22,7 @@ #include <inttypes.h> #include <stdbool.h> +#include <fribidi.h> #include <ft2build.h> #include FT_FREETYPE_H #include FT_GLYPH_H @@ -186,6 +187,7 @@ typedef struct { typedef struct { GlyphInfo *glyphs; + FriBidiChar *event_text; int length; LineInfo *lines; int n_lines; diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c index 6cb2ebf..44f8e7b 100644 --- a/libass/ass_shaper.c +++ b/libass/ass_shaper.c @@ -50,7 +50,7 @@ struct ass_shaper { // FriBidi log2vis int n_glyphs, n_pars; - FriBidiChar *event_text; + FriBidiChar *event_text; // just a reference, owned by text_info FriBidiCharType *ctypes; FriBidiLevel *emblevels; FriBidiStrIndex *cmap; @@ -103,8 +103,7 @@ void ass_shaper_info(ASS_Library *lib) static bool check_allocations(ASS_Shaper *shaper, size_t new_size, size_t n_pars) { if (new_size > shaper->n_glyphs) { - if (!ASS_REALLOC_ARRAY(shaper->event_text, new_size) || - !ASS_REALLOC_ARRAY(shaper->ctypes, new_size) || + if (!ASS_REALLOC_ARRAY(shaper->ctypes, new_size) || #ifdef USE_FRIBIDI_EX_API (shaper->bidi_brackets && !ASS_REALLOC_ARRAY(shaper->btypes, new_size)) || #endif @@ -128,7 +127,6 @@ void ass_shaper_free(ASS_Shaper *shaper) { ass_cache_done(shaper->metrics_cache); free(shaper->features); - free(shaper->event_text); free(shaper->ctypes); #ifdef USE_FRIBIDI_EX_API free(shaper->btypes); @@ -974,6 +972,7 @@ bool ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) int i, ret, last_break; FriBidiParType dir, *pdir; 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++) |