From ed62c02763237146517e8d7a8e0cbc01b717cb41 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Wed, 9 Feb 2011 01:27:22 +0100 Subject: [PATCH] Simplify word wrapping and fix possible endless loop wrap_lines_smart() got stuck if there was a long line without spaces followed by a hard linebreak. When the loop got to the '\n' character the hard linebreak was not handled because the line was already over wrap length and soft linebreak handling had precedence. Then at the end of the loop body the code noted that the hard linebreak hadn't yet been handled, and the same glyph needed to be reprocessed for that. However, the soft linebreak code hadn't actually done anything because there was no space to break at, and thus the loop repeated from the exact same state forever. Handle this by removing the check for an additional hard linebreak after a soft linebreak, which stepped back by one char. This is a very marginal case and shouldn't really matter in practice. Original patch and parts of this message by uau. --- libass/ass_render.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/libass/ass_render.c b/libass/ass_render.c index 480fc4a..8ca6911 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1434,10 +1434,9 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width) break_type = 0; s1 = text_info->glyphs; // current line start for (i = 0; i < text_info->length; ++i) { - int break_at; + int break_at = -1; double s_offset, len; cur = text_info->glyphs + i; - break_at = -1; s_offset = d6_to_double(s1->bbox.xMin + s1->pos.x); len = d6_to_double(cur->bbox.xMax + cur->pos.x) - s_offset; @@ -1446,10 +1445,10 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width) break_at = i; ass_msg(render_priv->library, MSGL_DBG2, "forced line break at %d", break_at); - } - - if ((len >= max_text_width) - && (render_priv->state.wrap_style != 2)) { + } else if (cur->symbol == ' ') { + last_space = i; + } else if (len >= max_text_width + && (render_priv->state.wrap_style != 2)) { break_type = 1; break_at = last_space; if (break_at >= 0) @@ -1475,14 +1474,6 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width) s_offset = d6_to_double(s1->bbox.xMin + s1->pos.x); text_info->n_lines++; } - - if (cur->symbol == ' ') - last_space = i; - - // make sure the hard linebreak is not forgotten when - // there was a new soft linebreak just inserted - if (cur->symbol == '\n' && break_type == 1) - i--; } #define DIFF(x,y) (((x) < (y)) ? (y - x) : (x - y)) exit = 0; -- 2.40.0