Browse Source

codec: substtml: handle set node

pull/54/head
Francois Cartegnie 10 years ago
parent
commit
1eafa71b46
  1. 89
      modules/codec/ttml/substtml.c

89
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 )
{

Loading…
Cancel
Save