[vlc-commits] codec: webvtt: fix regionless cues position
Francois Cartegnie
git at videolan.org
Fri Jan 19 18:45:26 CET 2018
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jan 19 16:18:48 2018 +0100| [8c861a3c4913da41fda7bab1980d445e93d03a5f] | committer: Francois Cartegnie
codec: webvtt: fix regionless cues position
somehow limited
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8c861a3c4913da41fda7bab1980d445e93d03a5f
---
modules/codec/webvtt/subsvtt.c | 133 +++++++++++++++++++++++++++++++++++++----
1 file changed, 121 insertions(+), 12 deletions(-)
diff --git a/modules/codec/webvtt/subsvtt.c b/modules/codec/webvtt/subsvtt.c
index bb0cb60c34..d22d80d94a 100644
--- a/modules/codec/webvtt/subsvtt.c
+++ b/modules/codec/webvtt/subsvtt.c
@@ -86,7 +86,7 @@ typedef struct
enum webvtt_align_e linealign;
float position;
enum webvtt_align_e positionalign;
- float size;
+ webvtt_auto_value_t size;
enum webvtt_align_e align;
} webvtt_cue_settings_t;
@@ -203,6 +203,89 @@ static bool parse_percent_tuple( const char *psz, float *x, float *y )
return false;
}
+typedef struct
+{
+ float x,y,w,h;
+} webvtt_rect_t;
+
+static void webvtt_get_cueboxrect( const webvtt_cue_settings_t *p_settings,
+ webvtt_rect_t *p_rect )
+{
+ float extent;
+ float indent_anchor_position;
+ enum webvtt_align_e alignment_on_indent_anchor;
+
+ /* Position of top or left depending on writing direction */
+ float line_offset;
+ if( !p_settings->line.b_auto ) /* numerical */
+ {
+ if( p_settings->b_snap_to_lines ) /* line # */
+ line_offset = p_settings->line.value /
+ (WEBVTT_REGION_LINES_COUNT * WEBVTT_LINE_TO_HEIGHT_RATIO);
+ else
+ line_offset = p_settings->line.value;
+ }
+ else line_offset = 1.0;
+
+ if( p_settings->position < 0 )
+ {
+ if( p_settings->align == WEBVTT_ALIGN_LEFT )
+ indent_anchor_position = 0;
+ else if( p_settings->align == WEBVTT_ALIGN_RIGHT )
+ indent_anchor_position = 1.0;
+ else
+ indent_anchor_position = 0.5; /* center */
+ }
+ else indent_anchor_position = p_settings->position;
+
+ if( p_settings->positionalign == WEBVTT_ALIGN_AUTO )
+ {
+ /* text align */
+ if( p_settings->align == WEBVTT_ALIGN_LEFT ||
+ p_settings->align == WEBVTT_ALIGN_RIGHT )
+ alignment_on_indent_anchor = p_settings->align;
+ else
+ alignment_on_indent_anchor = WEBVTT_ALIGN_CENTER;
+ }
+ else alignment_on_indent_anchor = p_settings->positionalign;
+
+ if( !p_settings->size.b_auto )
+ extent = p_settings->size.value;
+ else
+ extent = 0.0;
+
+ /* apply */
+
+ /* we need 100% or size for inner_align to work on writing direction */
+ if( p_settings->vertical == WEBVTT_ALIGN_AUTO ) /* Horizontal text */
+ {
+ p_rect->y = line_offset > 0 ? line_offset : 1.0 + line_offset;
+ p_rect->w = (extent) ? extent : 1.0;
+ if( indent_anchor_position > 0 &&
+ (alignment_on_indent_anchor == WEBVTT_ALIGN_LEFT ||
+ alignment_on_indent_anchor == WEBVTT_ALIGN_START) )
+ {
+ p_rect->x = indent_anchor_position;
+ p_rect->w -= p_rect->x;
+ }
+ }
+ else /* Vertical text */
+ {
+ if( p_settings->vertical == WEBVTT_ALIGN_LEFT )
+ p_rect->x = line_offset > 0 ? 1.0 - line_offset : -line_offset;
+ else
+ p_rect->x = line_offset > 0 ? line_offset : 1.0 + line_offset;
+ p_rect->y = (extent) ? extent : 1.0;
+
+ if( indent_anchor_position > 0 &&
+ alignment_on_indent_anchor == WEBVTT_ALIGN_START )
+ {
+ p_rect->y = indent_anchor_position;
+ p_rect->h -= p_rect->y;
+ }
+ }
+}
+
static void webvtt_cue_settings_ParseTuple( webvtt_cue_settings_t *p_settings,
const char *psz_key, const char *psz_value )
{
@@ -217,6 +300,7 @@ static void webvtt_cue_settings_ParseTuple( webvtt_cue_settings_t *p_settings,
}
else if( !strcmp( psz_key, "line" ) )
{
+ p_settings->line.b_auto = false;
if( strchr( psz_value, '%' ) )
{
parse_percent( psz_value, &p_settings->line.value );
@@ -224,7 +308,6 @@ static void webvtt_cue_settings_ParseTuple( webvtt_cue_settings_t *p_settings,
}
else
p_settings->line.value = us_strtof( psz_value, NULL );
-
/* else auto */
const char *psz_align = strchr( psz_value, ',' );
@@ -256,7 +339,8 @@ static void webvtt_cue_settings_ParseTuple( webvtt_cue_settings_t *p_settings,
}
else if( !strcmp( psz_key, "size" ) )
{
- parse_percent( psz_value, &p_settings->size );
+ parse_percent( psz_value, &p_settings->size.value );
+ p_settings->size.b_auto = false;
}
else if( !strcmp( psz_key, "region" ) )
{
@@ -318,7 +402,8 @@ static void webvtt_cue_settings_Init( webvtt_cue_settings_t *p_settings )
p_settings->linealign = WEBVTT_ALIGN_START;
p_settings->position = -1;
p_settings->positionalign = WEBVTT_ALIGN_AUTO;
- p_settings->size = 1.0; /* 100% */
+ p_settings->size.value = 1.0; /* 100% */
+ p_settings->size.b_auto = true;
p_settings->align = WEBVTT_ALIGN_CENTER;
}
@@ -1658,21 +1743,45 @@ static void RenderRegions( decoder_t *p_dec, mtime_t i_start, mtime_t i_stop )
v.i_top = 0.0;
/* !Variables */
- text_segment_t *p_segments = ConvertCuesToSegments( p_dec, i_start, i_stop, &v, p_rlcue );
- if( p_segments )
+ for( const webvtt_dom_cue_t *p_cue = p_rlcue; p_cue;
+ p_cue = (const webvtt_dom_cue_t *) p_cue->p_next )
{
+ if( p_cue->type != NODE_CUE )
+ continue;
+
+ if( p_cue->i_start > i_start || p_cue->i_stop <= i_start )
+ continue;
+
+ text_segment_t *p_segments = ConvertCueToSegments( p_dec, &v, p_cue );
+ if( !p_segments )
+ continue;
+
CreateSpuOrNewUpdaterRegion( p_dec, &p_spu, &p_updtregion );
- if( !p_spu || !p_updtregion )
+ if( !p_updtregion )
{
text_segment_ChainDelete( p_segments );
+ continue;
}
- else
+
+ if( p_cue->settings.line.b_auto )
{
p_updtregion->align = SUBPICTURE_ALIGN_BOTTOM;
- p_updtregion->inner_align = GetCueTextAlignment( p_rlcue );
-
- p_updtregion->p_segments = p_segments;
}
+ else
+ {
+ webvtt_rect_t rect = { 0,0,0,0 };
+ webvtt_get_cueboxrect( &p_cue->settings, &rect );
+ p_updtregion->align = SUBPICTURE_ALIGN_TOP|SUBPICTURE_ALIGN_LEFT;
+ p_updtregion->origin.x = rect.x;
+ p_updtregion->origin.y = rect.y;
+ p_updtregion->extent.x = rect.w;
+ p_updtregion->extent.y = rect.h;
+ p_updtregion->flags |= (UPDT_REGION_ORIGIN_X_IS_RATIO|UPDT_REGION_ORIGIN_Y_IS_RATIO|
+ UPDT_REGION_EXTENT_X_IS_RATIO|UPDT_REGION_EXTENT_Y_IS_RATIO);
+ }
+
+ p_updtregion->inner_align = GetCueTextAlignment( p_cue );
+ p_updtregion->p_segments = p_segments;
}
}
@@ -1681,7 +1790,7 @@ static void RenderRegions( decoder_t *p_dec, mtime_t i_start, mtime_t i_stop )
p_spu->i_start = i_start;
p_spu->i_stop = i_stop;
p_spu->b_ephemer = true; /* !important */
- p_spu->b_absolute = false;
+ p_spu->b_absolute = false; /* can't be absolute as snap to lines can overlap ! */
subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys;
p_spu_sys->p_default_style->f_font_relsize = WEBVTT_DEFAULT_LINE_HEIGHT_VH /
More information about the vlc-commits
mailing list