summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOneric <oneric@oneric.stub>2021-03-19 00:34:33 +0100
committerOneric <oneric@oneric.stub>2022-08-19 19:03:38 +0200
commit169862065a70bedd202bce3c2f92f0e880f70029 (patch)
treeb77e92dba687abd60eaa3fc4fbb01d2c80f8b95d
parentc610332853b6581802f07229101c0889ed731ee5 (diff)
downloadlibass-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.c8
-rw-r--r--libass/ass_render.h2
-rw-r--r--libass/ass_shaper.c7
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++)