[vlc-commits] codec: substtml: handle set node
Francois Cartegnie
git at videolan.org
Tue Feb 14 17:51:01 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Feb 14 15:12:54 2017 +0100| [1eafa71b46312b575df60b2cc4e4c8e23bb254f8] | committer: Francois Cartegnie
codec: substtml: handle set node
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1eafa71b46312b575df60b2cc4e4c8e23bb254f8
---
modules/codec/ttml/substtml.c | 89 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 76 insertions(+), 13 deletions(-)
diff --git a/modules/codec/ttml/substtml.c b/modules/codec/ttml/substtml.c
index c244e20..f78bd4a 100644
--- a/modules/codec/ttml/substtml.c
+++ b/modules/codec/ttml/substtml.c
@@ -113,6 +113,37 @@ static void ttml_region_Delete( ttml_region_t *p_region )
free( p_region );
}
+static ttml_style_t * ttml_style_Duplicate( const ttml_style_t *p_src )
+{
+ ttml_style_t *p_dup = ttml_style_New( );
+ if( p_dup )
+ {
+ *p_dup = *p_src;
+ p_dup->font_style = text_style_Duplicate( p_src->font_style );
+ }
+ return p_dup;
+}
+
+static void ttml_style_Merge( const ttml_style_t *p_src, ttml_style_t *p_dst )
+{
+ if( p_src && p_dst )
+ {
+ if( p_src->font_style )
+ {
+ if( p_dst->font_style )
+ text_style_Merge( p_dst->font_style, p_src->font_style, true );
+ else
+ p_dst->font_style = text_style_Duplicate( p_src->font_style );
+ }
+
+ if( p_src->b_direction_set )
+ {
+ p_dst->b_direction_set = true;
+ p_dst->i_direction = p_src->i_direction;
+ }
+ }
+}
+
static ttml_region_t *ttml_region_New( )
{
ttml_region_t *p_ttml_region = calloc( 1, sizeof( ttml_region_t ) );
@@ -410,6 +441,18 @@ static void DictMergeWithRegionID( ttml_context_t *p_ctx, const char *psz_id,
}
}
+static void DictToTTMLStyle( const vlc_dictionary_t *p_dict, ttml_style_t *p_ttml_style )
+{
+ for( int i = 0; i < p_dict->i_size; ++i )
+ {
+ for ( vlc_dictionary_entry_t* p_entry = p_dict->p_entries[i];
+ p_entry != NULL; p_entry = p_entry->p_next )
+ {
+ FillTTMLStyle( p_entry->psz_key, p_entry->p_value, p_ttml_style );
+ }
+ }
+}
+
static ttml_style_t * InheritTTMLStyles( ttml_context_t *p_ctx, tt_node_t *p_node )
{
assert( p_node );
@@ -435,14 +478,7 @@ static ttml_style_t * InheritTTMLStyles( ttml_context_t *p_ctx, tt_node_t *p_nod
if( merged.i_size && merged.p_entries[0] && (p_ttml_style = ttml_style_New()) )
{
- for( int i = 0; i < merged.i_size; ++i )
- {
- for ( vlc_dictionary_entry_t* p_entry = merged.p_entries[i];
- p_entry != NULL; p_entry = p_entry->p_next )
- {
- FillTTMLStyle( p_entry->psz_key, p_entry->p_value, p_ttml_style );
- }
- }
+ DictToTTMLStyle( &merged, p_ttml_style );
}
vlc_dictionary_clear( &merged, NULL, NULL );
@@ -576,7 +612,7 @@ static void AppendLineBreakToRegion( ttml_region_t *p_region )
}
static void AppendTextToRegion( ttml_context_t *p_ctx, const tt_textnode_t *p_ttnode,
- ttml_region_t *p_region )
+ const ttml_style_t *p_set_styles, ttml_region_t *p_region )
{
text_segment_t *p_segment;
@@ -589,6 +625,9 @@ static void AppendTextToRegion( ttml_context_t *p_ctx, const tt_textnode_t *p_tt
ttml_style_t *s = InheritTTMLStyles( p_ctx, p_ttnode->p_parent );
if( s )
{
+ if( p_set_styles )
+ ttml_style_Merge( p_set_styles, s );
+
p_segment->style = s->font_style;
s->font_style = NULL;
@@ -606,7 +645,9 @@ static void AppendTextToRegion( ttml_context_t *p_ctx, const tt_textnode_t *p_tt
}
static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t *p_node,
- ttml_region_t *p_region, int64_t i_playbacktime )
+ ttml_region_t *p_region,
+ const ttml_style_t *p_upper_set_styles,
+ int64_t i_playbacktime )
{
if( i_playbacktime != -1 &&
!tt_timings_Contains( &p_node->timings, i_playbacktime ) )
@@ -626,12 +667,31 @@ static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t
AppendLineBreakToRegion( p_region );
}
+ /* Styles from <set> element */
+ ttml_style_t *p_set_styles = (p_upper_set_styles)
+ ? ttml_style_Duplicate( p_upper_set_styles )
+ : NULL;
+
for( const tt_basenode_t *p_child = p_node->p_child;
p_child; p_child = p_child->p_next )
{
if( p_child->i_type == TT_NODE_TYPE_TEXT )
{
- AppendTextToRegion( p_ctx, (const tt_textnode_t *) p_child, p_region );
+ AppendTextToRegion( p_ctx, (const tt_textnode_t *) p_child,
+ p_set_styles, p_region );
+ }
+ else if( !tt_node_NameCompare( ((const tt_node_t *)p_child)->psz_node_name, "set" ) )
+ {
+ const tt_node_t *p_set = (const tt_node_t *)p_child;
+ if( i_playbacktime == -1 ||
+ tt_timings_Contains( &p_set->timings, i_playbacktime ) )
+ {
+ if( p_set_styles != NULL || (p_set_styles = ttml_style_New()) )
+ {
+ /* Merge with or create a local set of styles to apply to following childs */
+ DictToTTMLStyle( &p_set->attr_dict, p_set_styles );
+ }
+ }
}
else if( !tt_node_NameCompare( ((const tt_node_t *)p_child)->psz_node_name, "br" ) )
{
@@ -640,9 +700,12 @@ static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t
else
{
ConvertNodesToRegionContent( p_ctx, (const tt_node_t *) p_child,
- p_region, i_playbacktime );
+ p_region, p_set_styles, i_playbacktime );
}
}
+
+ if( p_set_styles )
+ ttml_style_Delete( p_set_styles );
}
static tt_node_t *ParseTTML( decoder_t *p_dec, const uint8_t *p_buffer, size_t i_buffer )
@@ -688,7 +751,7 @@ static ttml_region_t *GenerateRegions( tt_node_t *p_rootnode, int64_t i_playback
ttml_context_t context;
context.p_rootnode = p_rootnode;
vlc_dictionary_init( &context.regions, 1 );
- ConvertNodesToRegionContent( &context, p_bodynode, NULL, i_playbacktime );
+ ConvertNodesToRegionContent( &context, p_bodynode, NULL, NULL, i_playbacktime );
for( int i = 0; i < context.regions.i_size; ++i )
{
More information about the vlc-commits
mailing list