TTML - Overriding of style attributes in Region

Feb 21, 2014 at 6:26 PM
I have some TTML generated by a commercial Transformer (taking EIA-608 as an input).
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<tt ttp:frameRate="24" ttp:frameRateMultiplier="1000 1001" ttp:timeBase="smpte" xml:lang="en" xmlns="http://www.w3.org/ns/ttml" xmlns:m608="http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608" xmlns:smpte="http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt" xmlns:ttm="http://www.w3.org/ns/ttml#metadata" xmlns:ttp="http://www.w3.org/ns/ttml#parameter" xmlns:tts="http://www.w3.org/ns/ttml#styling">

  <head>
    <ttm:title>SMPTE-TT document</ttm:title>
    <styling>
      <style tts:color="white" tts:fontFamily="monospace" tts:fontSize="0.6c" tts:fontWeight="bold" xml:id="basic"/>
    </styling>
    <layout>
      <region tts:backgroundColor="transparent" xml:id="pop1"/>
    </layout>
  </head>
  <body>
    <div>
      <p begin="00:00:02:23" end="00:01:06:03" region="pop1" style="basic" tts:origin="27% 84%" xml:space="preserve">
        <span tts:backgroundColor="purple">Bilbo: "MY DEAR FRODO:</span>
      </p>
    </div>
  </body>
</tt>
The problem is that the caption is not displayed where it should be according to the origin. To make it work I have to move the tts:origin attribute into the region element.

I believe that this could be corrected in the TimedTextMarkerParser.BuildCaptions method and have put in a quick hack to test this theory. However I'd just like to contact the TTML Experts here to find out if this is a problem they are aware of and whether this is the correct area in which to amalgamate the referred region and apply any overrides/modifications (as I believe origin may be an additive transformation).

My hack at the moment:

instead of
if (captionRegionsHash.TryGetValue(regionName, out captionRegion))
{
    captionRegion.Children.Add(captionElement);
    captionElement.Index = captionRegion.Children.Count;
}
I have
if (captionRegionsHash.TryGetValue(regionName, out captionRegion))
{
    // If the captionElement implements any style that overrides the
    // value from the hash, then clone and add the new region.
    if (captionElement.Style.Origin != captionRegion.Style.Origin)
    {
        var newCaptionRegion = new CaptionRegion
        {
            Begin = captionRegion.Begin,
            CaptionElementType = captionRegion.CaptionElementType,
            End = captionRegion.End,
            Style = captionRegion.Style.Clone()
        };

        newCaptionRegion.Style.Origin = captionElement.Style.Origin;
        captionRegionsHash.Add(Guid.NewGuid().ToString(), newCaptionRegion);
        newCaptionRegion.Children.Add(captionElement);
        captionElement.Index = newCaptionRegion.Children.Count;
    }
    else
    {
        captionRegion.Children.Add(captionElement);
        captionElement.Index = captionRegion.Children.Count;
    }
}
There is also the question of the implicit region of the whole picture when a layout region is not specified to consider. I hope this makes sense. if not I can blame spending a few hours stepping through unfamiliar code :)
Feb 24, 2014 at 1:04 AM
I've done some more investigation and I believe the correct place to fix this is in CaptionBlockRegion.xaml.cs.

In the ShowCaption method, you need to calculate the origin at which you want to display the caption and then call UpdateSize.
private void ShowCaption(TimedTextElement timedTextElement)
        {
            var caption = timedTextElement as CaptionElement;
            
            if (caption != null)
            {
                caption.CalculateCurrentStyle(_mediaPosition);

                // Jim Hack
                this.CaptionRegion.CurrentStyle.Origin = caption.Style.Origin;
                this.CaptionRegion.Style.Origin = caption.Style.Origin;
                this.UpdateSize();
                
                var uiElement = RenderElement(caption);
                if (uiElement != null)
                {
                    if (_activeElements.ContainsKey(caption))
                    {
                        HideCaption(timedTextElement);
                    }
                    _activeElements.Add(caption, uiElement);
                    captionsPanel.Children.Clear();
                    _activeElements.OrderBy(i => i.Key.Index)
                                   .ForEach(i => captionsPanel.Children.Add(i.Value));
                }
            }
        }
Any comments from the TTML guys on the project?
Mar 23, 2014 at 2:30 PM
you could post a patch under PATCHES in the source code section