From 2863a55a89c2237a128eadc8c0688df8a8c299fa Mon Sep 17 00:00:00 2001 From: Chris Bass Date: Tue, 27 Feb 2018 10:07:18 +0000 Subject: [PATCH] ttml: Add support for IMSC 1.0.1 fillLineGap attribute Strictly speaking, the TTML spec requires that text backgrounds extend only to the font height of the related text, rather than to the vertical distance between lines. The result of this is that there will typically be vertical gaps between line backgrounds through which moving video can be seen. Since this was unnacceptable to some content providers, v1.0.1 of the IMSC spec (which profiles TTML) adds a new attribute, itts:fillLineGap[1], that allows content authors to specify that clients should extend text backgrounds such that there are no gaps between lines. This attribute is also going to be included in the next release of EBU-TT-D. This patch adds support for fillLineGap to ttmlparse and ttmlrender. [1] https://www.w3.org/TR/ttml-imsc1.0.1/#itts-fillLineGap https://bugzilla.gnome.org/show_bug.cgi?id=787071 --- ext/ttml/gstttmlrender.c | 39 +++++++++++++++++++++------------------ ext/ttml/subtitle.c | 1 + ext/ttml/subtitle.h | 7 +++++++ ext/ttml/ttmlparse.c | 6 ++++++ 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/ext/ttml/gstttmlrender.c b/ext/ttml/gstttmlrender.c index ffa41912f5..f8d063fe90 100644 --- a/ext/ttml/gstttmlrender.c +++ b/ext/ttml/gstttmlrender.c @@ -2031,8 +2031,14 @@ gst_ttml_render_render_block_elements (GstTtmlRender * render, block_metrics.line_height, block_metrics.baseline_offset); g_free (markup); - bg_offset = 0; - bg_height = block_metrics.line_height; + if (!block->style_set->fill_line_gap) { + bg_offset = + block_metrics.baseline_offset - ue->pango_font_metrics.baseline; + bg_height = ue->pango_font_metrics.height; + } else { + bg_offset = 0; + bg_height = block_metrics.line_height; + } bg_width = text_image->width; if (line_padding > 0) { @@ -2656,7 +2662,9 @@ gst_ttml_render_render_text_region (GstTtmlRender * render, /* Render each block and append to list. */ for (i = 0; i < gst_subtitle_region_get_block_count (region); ++i) { const GstSubtitleBlock *block; - GstTtmlRenderRenderedImage *rendered_block; + GstTtmlRenderRenderedImage *rendered_block, *block_bg_image, *tmp; + GstBuffer *block_bg_buf; + gint block_height; block = gst_subtitle_region_get_block (region, i); rendered_block = gst_ttml_render_render_text_block (render, block, text_buf, @@ -2684,22 +2692,17 @@ gst_ttml_render_render_text_region (GstTtmlRender * render, break; } - if (!gst_ttml_render_color_is_transparent (&block->style_set-> - background_color)) { - /* Draw block background rectangle and render block image over it */ - GstTtmlRenderRenderedImage *tmp = rendered_block; - GstBuffer *block_bg_buf; - GstTtmlRenderRenderedImage *block_bg_image; + tmp = rendered_block; - block_bg_buf = gst_ttml_render_draw_rectangle (window_width, - rendered_block->height, block->style_set->background_color); - block_bg_image = gst_ttml_render_rendered_image_new (block_bg_buf, 0, - rendered_block->y, window_width, rendered_block->height); - rendered_block = gst_ttml_render_rendered_image_combine (block_bg_image, - rendered_block); - gst_ttml_render_rendered_image_free (tmp); - gst_ttml_render_rendered_image_free (block_bg_image); - } + block_height = rendered_block->height + (2 * rendered_block->y); + block_bg_buf = gst_ttml_render_draw_rectangle (window_width, + block_height, block->style_set->background_color); + block_bg_image = gst_ttml_render_rendered_image_new (block_bg_buf, 0, 0, + window_width, block_height); + rendered_block = gst_ttml_render_rendered_image_combine (block_bg_image, + rendered_block); + gst_ttml_render_rendered_image_free (tmp); + gst_ttml_render_rendered_image_free (block_bg_image); rendered_block->y = 0; g_ptr_array_add (rendered_blocks, rendered_block); diff --git a/ext/ttml/subtitle.c b/ext/ttml/subtitle.c index e0c32faa1d..38d442d983 100644 --- a/ext/ttml/subtitle.c +++ b/ext/ttml/subtitle.c @@ -77,6 +77,7 @@ gst_subtitle_style_set_new (void) ret->extent_w = ret->extent_h = 0.0; ret->padding_start = ret->padding_end = ret->padding_before = ret->padding_after = 0.0; + ret->fill_line_gap = FALSE; return ret; } diff --git a/ext/ttml/subtitle.h b/ext/ttml/subtitle.h index 6724cc6d60..cf67fd4ef2 100644 --- a/ext/ttml/subtitle.h +++ b/ext/ttml/subtitle.h @@ -353,6 +353,12 @@ typedef enum { * @overflow: Defines what should happen if text and background rectangles * generated by rendering text blocks overflow the size of their containing * region. Applies only to #GstSubtitleRegions. + * @fill_line_gap: Controls whether the rendered backgrounds of text elements + * in a line fill the whole space between that line and adjacent lines or + * extends only to the font height of the text in the individual elements (thus + * this field controls whether or not there are gaps between backgrounds + * through which the underlying video can be seen). Applies only to + * #GstSubtitleBlocks. * * Holds a set of attributes that describes the styling and layout that apply * to #GstSubtitleRegion, #GstSubtitleBlock and/or #GstSubtitleElement objects. @@ -391,6 +397,7 @@ struct _GstSubtitleStyleSet GstSubtitleWritingMode writing_mode; GstSubtitleBackgroundMode show_background; GstSubtitleOverflowMode overflow; + gboolean fill_line_gap; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; diff --git a/ext/ttml/ttmlparse.c b/ext/ttml/ttmlparse.c index 57a6288fd1..e097644fb3 100644 --- a/ext/ttml/ttmlparse.c +++ b/ext/ttml/ttmlparse.c @@ -234,6 +234,7 @@ ttml_parse_style_set (const xmlNode * node) for (attr = node->properties; attr != NULL; attr = attr->next) { if (attr->ns && ((g_strcmp0 ((const gchar *) attr->ns->prefix, "tts") == 0) + || (g_strcmp0 ((const gchar *) attr->ns->prefix, "itts") == 0) || (g_strcmp0 ((const gchar *) attr->ns->prefix, "ebutts") == 0))) { ttml_style_set_add_attr (s, (const gchar *) attr->name, (const gchar *) attr->children->content); @@ -658,6 +659,11 @@ ttml_update_style_set (GstSubtitleStyleSet * style_set, TtmlStyleSet * tss, else style_set->overflow = GST_SUBTITLE_OVERFLOW_MODE_HIDDEN; } + + if ((attr = ttml_style_set_get_attr (tss, "fillLineGap"))) { + if (g_strcmp0 (attr, "true") == 0) + style_set->fill_line_gap = TRUE; + } }