diff libass/ass_render.c @ 28436:12e936031c36

Allow \be with arguments other than 0 or 1. Implement \blur. Patch by Grigori G, greg at chown ath cx.
author eugeni
date Sat, 07 Feb 2009 01:13:02 +0000
parents 0e90b97bee00
children 523cf5e9afcb
line wrap: on
line diff
--- a/libass/ass_render.c	Thu Feb 05 19:45:13 2009 +0000
+++ b/libass/ass_render.c	Sat Feb 07 01:13:02 2009 +0000
@@ -43,6 +43,8 @@
 
 #define MAX_GLYPHS 3000
 #define MAX_LINES 300
+#define BE_RADIUS 1.5
+#define BLUR_MAX_RADIUS 50.0
 
 static int last_render_id = 0;
 
@@ -80,6 +82,7 @@
 	ass_settings_t settings;
 	int render_id;
 	ass_synth_priv_t* synth_priv;
+	ass_synth_priv_t* synth_priv_blur;
 
 	ass_image_t* images_root; // rendering result is stored here
 	ass_image_t* prev_images_root;
@@ -112,6 +115,7 @@
 	int asc, desc; // font max ascender and descender
 //	int height;
 	int be; // blur edges
+	double blur; // gaussian blur
 	int shadow;
 	double frx, fry, frz; // rotation
 	
@@ -160,6 +164,7 @@
 	char detect_collisions;
 	uint32_t fade; // alpha from \fad
 	char be; // blur edges
+	double blur; // gaussian blur
 	int shadow;
 	int drawing_mode; // not implemented; when != 0 text is discarded, except for style override tags
 
@@ -258,7 +263,8 @@
 		goto ass_init_exit;
 	}
 
-	priv->synth_priv = ass_synth_init();
+	priv->synth_priv = ass_synth_init(BE_RADIUS);
+	priv->synth_priv_blur = ass_synth_init(BLUR_MAX_RADIUS);
 
 	priv->library = library;
 	priv->ftlibrary = ft;
@@ -688,7 +694,16 @@
 	if ((*p == '}') || (*p == 0))
 		return p;
 
-	if (mystrcmp(&p, "fsc")) {
+	if (mystrcmp(&p, "blur")) {
+		double val;
+		if (mystrtod(&p, &val)) {
+			val = (val < 0) ? 0 : val;
+			val = (val > BLUR_MAX_RADIUS) ? BLUR_MAX_RADIUS : val;
+			render_context.blur = val;
+		} else
+			render_context.blur = 0.0;
+	// ASS standard tags
+	} else if (mystrcmp(&p, "fsc")) {
 		char tp = *p++;
 		double val;
 		if (tp == 'x') {
@@ -985,9 +1000,12 @@
 		reset_render_context();
 	} else if (mystrcmp(&p, "be")) {
 		int val;
-		if (mystrtoi(&p, 10, &val))
-			render_context.be = val ? 1 : 0;
-		else
+		if (mystrtoi(&p, 10, &val)) {
+			// Clamp to 10, since high values need excessive CPU
+			val = (val < 0) ? 0 : val;
+			val = (val > 10) ? 10 : val;
+			render_context.be = val;
+		} else
 			render_context.be = 0;
 	} else if (mystrcmp(&p, "b")) {
 		int b;
@@ -1181,6 +1199,7 @@
 	render_context.scale_y = render_context.style->ScaleY;
 	render_context.hspacing = render_context.style->Spacing;
 	render_context.be = 0;
+	render_context.blur = 0.0;
 	render_context.shadow = render_context.style->Shadow;
 	render_context.frx = render_context.fry = 0.;
 	render_context.frz = M_PI * render_context.style->Angle / 180.;
@@ -1321,9 +1340,10 @@
 
 			// render glyph
 			error = glyph_to_bitmap(ass_renderer->synth_priv,
+					ass_renderer->synth_priv_blur,
 					info->glyph, info->outline_glyph,
 					&info->bm, &info->bm_o,
-					&info->bm_s, info->be);
+					&info->bm_s, info->be, info->blur);
 			if (error)
 				info->symbol = 0;
 
@@ -1815,6 +1835,7 @@
 		text_info.glyphs[text_info.length].effect_timing = render_context.effect_timing;
 		text_info.glyphs[text_info.length].effect_skip_timing = render_context.effect_skip_timing;
 		text_info.glyphs[text_info.length].be = render_context.be;
+		text_info.glyphs[text_info.length].blur = render_context.blur;
 		text_info.glyphs[text_info.length].shadow = render_context.shadow;
 		text_info.glyphs[text_info.length].frx = render_context.frx;
 		text_info.glyphs[text_info.length].fry = render_context.fry;
@@ -1839,6 +1860,7 @@
 		text_info.glyphs[text_info.length].hash_key.ch = code;
 		text_info.glyphs[text_info.length].hash_key.advance = shift;
 		text_info.glyphs[text_info.length].hash_key.be = render_context.be;
+		text_info.glyphs[text_info.length].hash_key.blur = render_context.blur;
 
 		text_info.length++;