summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-02-09 01:27:22 +0100
committerGrigori Goronzy <greg@blackbox>2011-02-09 01:27:22 +0100
commited62c02763237146517e8d7a8e0cbc01b717cb41 (patch)
tree8eda5c701814ba75337d096d159d9ca400482353
parent8113989290ed507efcfa98d30f89945150f32acb (diff)
downloadlibass-ed62c02763237146517e8d7a8e0cbc01b717cb41.tar.bz2
libass-ed62c02763237146517e8d7a8e0cbc01b717cb41.tar.xz
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.
-rw-r--r--libass/ass_render.c19
1 files 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;