Conversion of EBU-TT-Live documents to EBU-TT-D documents¶
The ebu_tt_live.documents.converters.ebutt3_to_ebuttd()
function
creates an EBUTTDDocument from an EBUTT3Document using the helper class
ebu_tt_live.bindings.converters.ebutt3_ebuttd.EBUTT3EBUTTDConverter
.
This class manages various possible complications, including a significant set of constraints about font size.
Note that conversion to EBU-TT-D was not in scope for this project and therefore it was not implemented fully.
Here’s some documentation from the coding process that captures some of our internal conversation about how to map font sizes, to give an idea of the complexity.
The problem¶
Convert an EBU-TT part 3 document to EBU-TT-D
EBU-TT part 3 uses fonSize in 3 datatypes: cells, pixels and percentage. EBU-TT-D uses percentage fontSize only and prohibits pixels.
Percent values relate to the parent element or the cell size.
In order to be converted the sizes need to be translated from pixels/cells to percentages.
The relationship between parent and child element is important when percentages
are used because the child modulates the computed fontSize of the parent container.
However, it is an override when it comes to the other two data types. In order to be
converted, an absolute size needs to be calculated. According to TTML the
computed fontSize value is an absolute value such as pixel. This poses a problem
because the tts:extent
attribute of the tt:tt
element is not always available to us.
But ttp:cellResolution
and ttp:pixelAspectRatio
are available because they have
a default value that is available.
Percentages and the EM square¶
Consider how the top level tts:fontSize
attribute is evaluated (say on the
region). If it is a percentage value of "100%"
then the EM square’s
horizontal and vertical size are both the height of the cell whose size is
defined by the ttp:cellResolution
attribute of the tt:tt
element.
However if it is a a percentage value of "100% 100%"
then the EM square’s
horizontal size is the width of a cell and its vertical size is the height of
a cell. Then any derived size, say a tts:fontSize
attribute specified on a
style
element referenced by a tt:p
element, is scaled in proportion to
its parent element’s font size (default is "100%"
as defined above. See
http://w3c.github.io/ttml2/spec/ttml2.html#style-attribute-fontSize for the
definitive explanation in TTML2 (this is the same as TTML1 but with more recent
editorial additions).
Let’s look at "1c 1c"
. In general the cell is not square. In fact the only
case when it would be square would be if the ratio of the cell resolution’s
horizontal and vertical components were the same as the ratio of the height and
the width of the rendering area. In pixels this would an equal height and width
if the pixels are square. If we see "1c"
then the same anamorphic scaling is
applied as above. "1c 1c"
is equivalent to "100% 100%"
on the region
element.
At this point there is a big difference of the default value assumption. Depending on what unit I assume the default value in the results are different.
More complications around children wth percentages
Let’s assume we have the following styles at hand:
<style id="S1c" fontSize="1c"/>
<style id="S100p" fontSize="100%"/>
<style id="S1c1c" fontSize="1c 1c"/>
<style id="S50p" fontSize="50%"/>
<style id="S20p50p" fontSize="20% 50%"/>
Example 1:
<div style="S50p">
<p style="S20p50p">Test text</p>
</div>
In this case, the EM square is first scaled to half height and
half width (in the <div>
) and then anamorphically scaled (in the <p>
)
again to 20%:50% of the size defined in the parent.
Example 2:
<div style="S1c1c">
<p style="S20p50p">Test text</p>
</div>
Here the <div>
overrides any value with absolute cell size.
The child <p>
anamorphically resizes relatively to the parent.
Example 3:
<div style="S1c">
<p style="S20p50p">Test text</p>
</div>
Here the parent element defines an EM square of 1c. The child element defines a tall glyph that is going to be scaled in the ratio 20%:50% of a cell.
What if we could figure out width from height
The obvious solution would be to work out a way to normalize font sizing to be always 2 dimensional and have simple algorithms deal with them (without having to cater for edge cases of S100p being completely different from S1c).
This solution would require knowing all these valies:
extent(in pixels), cellResolution, pixelAspectRatio
But in a processing pipeline where we need to convert from one format to another, having to know the presentation context of a rendering engine is not ideal. So the solution must make no assumptions about the final presentation size.
The solution¶
In the end we had to overload ebuttdt.PercentageFontSizeType
to have either
one value or two value variants, and then deal with those cases in the
ebu_tt_live.bindings.converters.ebutt3_ebuttd.EBUTT3EBUTTDConverter._get_font_size_style()
function.