Re: Line Height stacking strategy algorithm - approval needed

Copying public-tt due to general interest.

On Mon, Jan 20, 2014 at 3:41 PM, Pierre-Anthony Lemieux <>wrote:

> Hi Glenn,
> I am interested in understanding the impact of the proposed text on
> IMSC Section 7.2.3. Specifically,
> > tts:lineHeight values expressed using the percentage metric shall
> > be relative to the largest font size on the line.

I'm afraid that was never the case, in none of TTML, XSL-FO, or CSS.

TTML1 1e [1] specified that percentage on tts:lineHeight is "relative to
this element's font size". This hasn't changed in TTML1 2e [2] or TTML2
[3]. Further, this is consistent with both XSL-FO, which defines [4]
percentage on this property by referring to CSS2 text [5]:

"The computed value of the property is this percentage multiplied by the
element's computed font size. Negative values are illegal."

The "element" referred to by "element's computed font size" is the element
on which tts:lineHeight is specified. So, if a percentage is specified on
tt:p, e.g.,

<tt:p tts:lineHeight="120%"/>

then % is resolved with respect to the computed font size of tt:p.


> Is this consistent with the following?
> "Furthermore, it is the intention of this specification that the
> allocation rectangle of a line be consistent with the
> per-inline-height-rectangle as defined by [XSL 1.1], § 4.5, i.e., that
> a CSS-style line box stacking strategy be used."

Keep in mind that you now have transitioned from talking about (1) the
property tts:lineHeight to (2) the algorithm for computing the height of
each line area (box) which uses the property tts:lineHeight as a parameter.

> > White space in excess of the largest font size on the line shall be
> allocated
> > evenly top and bottom (half-leading). Note that inter-baseline separation
> >  includes any leading.

I gather that this text was written by you in IMSC, and synthesized from
your working understanding, yes?

First, we need to distinguish between the leading that applies to line
areas and the leading that applies to an inline area child of a line area.

To diagram this a bit, we have:

(1) block areas generated by formatting an fo:block (tt:p)

BA*0* ... BA*m-1*

(2) line area children of BA*0* ... BA*m-1*

LA0,0 ... LA0,i-1 - line area children of BA0
LA1,0 ... LA1,j-1- line area children of BA1
LA2,0 ... LA2,k-1 - line area children of BA2

(3) inline area children of LAm,n

IA0,0,0 ... IA0,0,p-1 - inline area children of LA0,0
IA0,1,0 ... IA0,1,q-1 - inline area children of LA0,1

Using XSL-FO terminology [6], we need to distinguish between the leading of
an *expanded-nominal-requested-line-rectangle* (of a line area) and the
leading of an *expanded-rectangle* (of each inline area child of a line

The former leading is derived from the half-leading trait that applies to
each block area BA*m* generated by tt:p, and this trait is defined as
follows [7]:

"The .minimum, .optimum, and .maximum components of the *half-leading* trait
are set to 1/2 the difference of the computed value of the
*line-height* property
and the computed value of the sum of the *text-altitude* and *text-depth*

Here, the properties referenced (line-height, text-altitude, and
text-depth) refer to the computed values of these properties on the
fo:block element (our tt:p element), which, in turn are based on the
computed value of the font-size and font-family properties [*that apply to
this block element*].

So, for example, if one has:

<tt:p tts:fontSize="10px" tts:fontFamily="arial" tts:lineHeight="120%"/>

Then we have:

computed(fontSize) := 10px
computed(lineHeight) := 12px
computed(textAltitude) := scale(depthMetricOf(arial), 10px), let's say this
is 8px
computed(textDepth) := scale(depthMetricOf(arial), 10px), let's say this is

Assuming for a moment that the sum of computed(textAltitude) and
computed(textDepth) is 10px (which need not necessarily hold since we don't
control the font's metrics), then the half leading trait for each
BA*m*generated by this tt:p would be 1px, i.e., 1/2 of (12px - 10px).

Thus, the *expanded-nominal-requested-line-rectangle* of each line area
generated from this tt:p will have a half leading of 1px, or in diagram:


1px - before half leading

8px - text altitude of scaled font that applies to tt:p

2px - text depth of scaled font that applies to tt:p

1px - after half leading


Now, we have to look at the *expanded-rectangle* of each inline area child
of a line area. Since (at present) we have no replaced inline elements in
TTML, we will focus on non-replaced elements, namely immediate text node or
tt:span children of tt:p. These children will generate inline areas that
are assigned to specific line area children of the sequence of block areas
generated by tt:p. For this discussion, we will assume, without loss of
generality, that each inline area contains only glyph areas (and does not
contain a nested non-glyph, inline area).

Each glyph area child of a generated inline area is associated with a font
and a font size. It is also associated with a "normal" line height. We
don't actually say this anywhere, but this follows from the CSS definitions
of line height calculations [8], which follows from XSL-FO references to
CSS semantics.

In TTML, we could define (but have not yet defined) that style property
tts:lineHeight additionally applies to tt:span; however, at present we
define that it only applies to tt:p. Nevertheless, both XSL-FO and CSS
assume (or make explicit) that each glyph area is associated with a *line
height* parameter from which a leading for that glyph area might computed.
For example, see the following [8] (emphasis added):

"User agent must align the glyphs in a non-replaced inline box to each
other by their relevant baselines. Then, for each glyph, determine the A
 and D. Note that glyphs in a single element may come from different fonts
and thus need not all have the same A and D."

"Still for each glyph, determine the leading L to add, where L =
'line-height' <>
 - AD. Half the leading is added above A and the other half below D, giving
the glyph and its leading a total height above the baseline of A' = A + L/2
and a total depth of D' = D + L/2."

"The height of the inline box encloses all glyphs and their half-leading on
each side and is thus exactly 'line-height'."


Actual implementations of CSS (and XSL-FO) use a similar algorithm
presently defined in TTML2 [9] to determine the *line height* parameter for
each glyph (or inline) area, including the derived half-leading parameter.
I say similar because the algorithm in [9] is currently expressed only with
reference to the block (paragraph) and not each inline element, such as an
explicit or anonymous span. Let's just say that the same algorithm is used,
i.e., LH for a glyph area is determined by using the ascent (altitude),
descent (depth), and line gap (leading) metrics, or in their absence, by
using a fixed percentage of the scaled font size, say 125%.


Now, we can determine a half leading for each glyph area that appears in a
line area, and thus, can determine the height of each *expanded-rectangle* by
aligning the baseline of the glyphs in the line, then computing the maximum
ascent, maximum descent, and the half leading that applies to each (locally
contiguous) run of glyphs associated with the same font and font size.

This finally gives enough information to complete the final step defined by
XSL-FO in determining the height of the per-inline-height-rectangle of a
line [6] as:

"The extent of the per-inline-height-rectangle in the
block-progression-direction is then defined to be the minimum required to
enclose both the expanded-nominal-requested-line-rectangle and the
expanded-rectangles of all the inline-areas stacked within the line-area."

> So "per-inline-height-rectangle" calls for "half-leading" if the
> "area's allocation-rectangle is specified to be the
> normal-allocation-rectangle by the description of the generating
> formatting object". Is this the case?

Yes, provided you keep in mind that there is more than one potential
"half-leading" that applies: (1) the half-leading that applies to the
expanded-nominal-requested-line-rectangle, derived from the font, font
size, and line height that applies to the block (tt;p) as a whole and (2)
the half-leading that applies to each expanded-rectangle on a line, derived
from the font, font size, and line height that applies to each glyph inline
area in the line.

Further, it isn't just a matter of maximizing these line heights, but must
take into account baseline alignment and determining the maximum ascent and
descent points in a line and the half leadings that apply to those points.

> > If the computed value of tts:lineHeight is not supported, then a
> presentation processor
> > shall use the next highest supported value.
> Would this be subject to the round half-up rule of Section 8.2.13, and
> so not necessarily the "next highest supported value"?

In some ways, talking about "support" for a specific lineHeight computed
value is a bit of a red herring. What we probably should do instead is talk
about support for a specific line area's height *after* performing the
algorithms described above. For example, one might imagine that some
devices will want to align lines to a device pixel value, while others,
perhaps those using anti-aliasing, might choose do not enforce such a

So what we have in the text at present is definitely not perfect, and very
likely misleading.

> Looking forward to your thoughts.
> Thanks,
> -- Pierre
> ---------- Forwarded message ----------
> From: Nigel Megitt <>
> Date: Fri, Jan 17, 2014 at 6:17 AM
> Subject: Line Height stacking strategy algorithm - approval needed
> To: Timed Text Working Group <>
> As discussed in yesterday's TTWG meeting, as part of the fulfilment of
> actions 219 [1] and 221 [2] Glenn has edited the TTML2 editor's draft
> to incorporate an algorithm for computing the value of line height,
> based on the code used by Mozilla, blink and webkit. This can
> additionally be considered part of the solution to the line height
> problem which has also been raised in issues 275 [3] and 284 [4].
> The algorithm can be found at [5] in section 8.2.13 tts:lineHeight.
> I won't attempt to repeat Glenn's explanation of this algorithm, which
> I scribed as best I could yesterday, except to note what may appear at
> first to be a substantive change to some, that the "125% of fontSize"
> rule does not always apply, but applies only when the font is not
> associated with "font metrics that specify altitude A, descent D, and
> line gap G".
> This algorithm is absent from CSS but, if this group's members are
> happy with it, we should communicate it to the CSS WG, to maximise the
> time for them to raise any potential issues, or indeed choose to adopt
> it into their own output documentation, which we could then
> potentially reference. Formally they will report any problems anyway
> at Last Call stage but I'd rather seek early agreement when possible.
> Please notify the group if there are any queries or objections to this
> algorithm as it stands.
> We noted in yesterday's call that it was not possible to verify that
> IE adopts the same algorithm, so it would be particularly useful if
> someone from Microsoft could confirm that they are happy with it –
> Jerry, this probably means you!
> Rather than making this an open-ended action I'll close this off and
> state that we have approval if there are no outstanding objections by
> the end of our next call on 30th Jan 2014.
> This email satisfies Action-260 [6].
> References
> [1] Action-219
> [2] Action-221
> [3] Issue-275
> [4] Issue-284
> [5] TTML2 Editor's draft, section on lineHeight
> [6] Action-260
> ----------------------------
> This e-mail (and any attachments) is confidential and may contain
> personal views which are not the views of the BBC unless specifically
> stated.
> If you have received it in error, please delete it from your system.
> Do not use, copy or disclose the information in any way nor act in
> reliance on it and notify the sender immediately.
> Please note that the BBC monitors e-mails sent or received.
> Further communication will signify your consent to this.
> ---------------------

Received on Tuesday, 21 January 2014 01:07:33 UTC