Fwd: Re: lineHeight

Thanks for the detailed walk through! It continues the discussion we had 
in a thread before [1].

To be clear that I got it right about the default value of line-height: 
If the computed line-height is the same as the largest font-size of a 
descendent and we assume the font-size of a p block is 14px for all 
descendant elements, than the computed line height is 14px. If we assume 
that the sum of the  computed values of the text-altitude and text-depth 
properties is not less than 14px than the leading is 0 or negative. Is 
this correct?

If this is the case the default value for line-height would generate a 
representation that is not very accessible.

I am not sure how much we can take the font-size/line-height dependency 
in CSS as reference but at least here a two-line subtitle would not be 
very readable if font-size and line-height have the same value (see 
http://jsfiddle.net/tairt/YdsWd/).

Best regards,

Andreas

1] http://lists.w3.org/Archives/Public/public-tt/2013Jul/0090.html 
<http://lists.w3.org/Archives/Public/public-tt/2013Jul/0090.html>


-------- Original-Nachricht --------
Betreff:  Re: lineHeight
Weitersenden-Datum:  Fri, 23 Aug 2013 02:55:03 +0000
Weitersenden-Von:  public-tt@w3.org
Datum:  Thu, 22 Aug 2013 20:54:09 -0600
Von:  Glenn Adams <glenn@skynav.com>
An:  Michael Dolan <mdolan@newtbt.com>
Kopie (CC):  TTWG <public-tt@w3.org>



Thanks for asking, as this is a complex area of functionality when 
having to wade through the more general models of both XSL-FO and CSS. 
See inline below for clarifications and answers, and at the end some 
additional useful information.

On Thu, Aug 22, 2013 at 4:55 PM, Michael Dolan <mdolan@newtbt.com 
<mailto:mdolan@newtbt.com>> wrote:

    Glenn and all-

    A cursory reading of TTML suggests lineHeight=fontSize.  But digging
    deeper into XSL, one might reach different conclusions in red (also
    marked “CONCLUSION”).

    [TTML 8.2.12]:

      tts:lineHeight

    If the value of this attribute is normal, then the initial value of
    the style property must be considered to be the same as the largest
    font size that applies to any descendant element.

    ….

    The semantics of the style property represented by this attribute
    are based upon that defined by [XSL 1.1], § 7.16.4.


First, we should quote the current TTML1 ED text, which was updated on 
July 12th [1] and 16th [2] to read as follows:

"If the value of this attribute is |normal|, then the computed value of 
the style property must be considered to be the same as the largest font 
size that applies to any descendant element in the intermediate 
synchronic document as determined by *9.3.2 Intermediate Synchronic 
Document Construction* 
<https://dvcs.w3.org/hg/ttml/raw-file/default/ttml1/spec/ttml1.html#semantics-region-layout-step-1>."

[1] https://dvcs.w3.org/hg/ttml/rev/00a9b799895d
[2] https://dvcs.w3.org/hg/ttml/rev/0355e9473d7e

This text, about the "largest font size", is intended to correspond to 
the following language in:

XSL-FO [3]:

"When an element contains text that is rendered in more than one font, 
user agents should determine the "line-height" value according to the 
largest font size."

[3] http://www.w3.org/TR/2006/REC-xsl11-20061205/#line-height

and CSS2.1 10.8.1 [4]:

"When an element contains text that is rendered in more than one font, 
user agents may determine the 'normal' 'line-height' 
<http://www.w3.org/TR/CSS2/visudet.html#propdef-line-height> value 
according to the largest font size."

[4] http://www.w3.org/TR/CSS2/visudet.html#propdef-line-height

Note that these two citations are identical except that CSS2.1 added 
'normal', while XSL-FO, which quotes CSS2, didn't make it explicit that 
this sentence was to be scoped by interpretation of what 'normal' means.

Note also the two changes [1][2] we made in TTML1 since PER:

  * correct "initial value" to read "computed value";
  * clarify that "descendant element" refers to descendants in the
    intermediate synchronic document, and not the source document;

In other words, this changed language is about determining what the 
computed value of 'normal' means, and which descendants apply in making 
that determination. For example, one may have read the prior language as 
including the font size of descendant elements that are not temporally 
active or are selected into a different region, both of which should not 
apply when resolving the computed value for 'normal'.

    [XSL 7.16.4]:

    Normal: Tells user agents to set the computed value to a
    "reasonable" value based on the font size of the element. The value
    has the same meaning as <number>. We recommend a computed value for
    "normal" between 1.0 to 1.2.

    <length>: The box height is set to this length.

    CONCLUSION: Therefore as TTML states that a value of "normal" "must
    be considered to be the same as the largest font size", I assume
    that the XSL 7.16.4 definition that is in effect is "<length>" with
    the value of the largest font size.

Correct. For example, if one has:

<p id="p1" tts:fontSize="12pt" tts:lineHeight="normal">
<span tts:fontSize="10pt">FOO</span>
<span tts:fontSize="12pt">BAR</span>
<span tts:fontSize="14pt">BAZ</span>
</p>

Then the resolved computed value of tts:lineHeight on the paragraph p1 
is "14pt". In other words, we could have specified the equivalent with:

<p id="p1" tts:fontSize="12pt" tts:lineHeight="14pt">...</p>

On the other hand, if this content mapped were selected into two 
regions, such as:

<p tts:fontSize="12pt" tts:lineHeight="normal">
<span region="r1" tts:fontSize="10pt">FOO</span>
<span region="r1" tts:fontSize="12pt">BAR</span>
<span region="r2" tts:fontSize="14pt">BAZ</span>
</p>

Then the computed line height that applies to p1 in region r1 would be 
12pt, but in region r2 would be 14pt.

    [TTML 8.2.12] continued:

    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.

Here's where things get complex to interpret (particularly when trying 
to decode the language in XSL-FO). However, before we do that, let's 
take note of some simplifying factors that hold in TTML than apply to 
XSL-FO and CSS:

In particular, in TTML1 (though perhaps not TTML2 when we introduce images):

  * tts:lineHeight only applies to the paragraph element p, and does not
    apply to span or br;
  * all inline children of p are non-replaceable (text) elements; i.e.,
    there are no replaceable elements like <img/> [if some profile
    introduces replaceable elements in a superset extension, then this
    simplifying assumption may not hold];

In general, in both XSL-FO and CSS, these assumptions don't hold, so the 
descriptive text in XSL-FO is more complex to interpret.

Before I attempt to explain the XSL-FO text, I will summarize the three 
line stacking strategies defined there:

*font-height*

Produces constant distance between the baselines of adjacent line areas. 
The height of a line area's allocation rectangle is the height of the 
*nominal-requested-line-rectangle*, which is the sum of the altitude and 
the depth, i.e., font size, of the font that applies to the containing 
block element (ignoring altitude and depth of the fonts that apply to 
the line area's child areas).

Line areas of a block are stacked (in the block progression dimension) 
so that the distance between baselines are constant and equal to the 
computed value of the line height property of the containing block 
element. This is accomplished by (1) computing the half-leading trait of 
a block area as half the difference between the computed value of the 
line-height property and the sum of the computed values of the 
text-altitude and text-depth properties, then (2) assigning this 
half-leading to the space-before and space-after traits of each line 
area generated by the block.

Note that half-leading is negative if line-height is less than altitude 
plus depth (font size), in which case line area rectangles will overlap.

*max-height*

Produces constant distance between the adjacent edges of consecutive 
line areas, i.e., between the after edge of line N and the before edge 
of line N+1. The height of a line area's allocation rectangle is the 
height of the *maximum-line-rectangle*, which is the greater of (a) the 
height of the nominal-requested-line-rectangle described above and (b) 
the sum of the maximum altitude and maximum depth of the /allocation 
rectangles/ of the line area's child inline areas.

If no child inline area has an altitude (distance above baseline) 
greater than the altitude of the containing block's font and no child 
inline area has a depth (distance below baseline) greater than the depth 
of the containing block's font, then the result will be identical to the 
*font-height* strategy.

Note that the /allocation rectangle/ of an inline area generated by an 
element comes in two flavors [5]:

  * normal-allocation-rectangle
  * large-allocation-rectangle

In general, non-replaceable elements, e.g., text, generate normal 
allocation rectangles, while replaceable elements, e.g., images, 
generate large-allocation-rectangles. The former "normal" variety *does 
not* include padding and border when computing its height, while the 
latter "large" variety *does* include padding and border.

[5] http://www.w3.org/TR/2006/REC-xsl11-20061205/#area-geo

Note further, and importantly (for what follows), that this strategy 
does not take into account (a) a different line height property of any 
non-replaceable child element and (b) the space (margin) before (top) 
and after (bottom) properties of any replaceable child element.

Half-leading computation and usage follows the same rules described 
above for the font-height strategy, meaning that half-leading may be 
negative, and thus cause line area rectangle overlap.

*line-height*

Effectively the same as the max-height strategy, except that (a) 
half-leading is computed on a per-line basis, (b) the half-leading of 
non-replaceable child inline elements is applied (rather than ignored), 
and (c) the margin (space) in the block progression dimension of 
replaceable child inline elements is applied (rather than ignored).

More specifically, the height of a line area's allocation rectangle is 
the height of the *per-inline-height-rectangle*, which is the greater of 
(a) the height of the expanded-nominal-requested-line-rectangle (see 
below) and (b) the sum of the maximum altitude and maximum depth of 
the expanded-rectangle (see below) of each of the line area's child 
inline areas.

The *expanded-nominal-requested-line-rectangle* is the same as the 
nominal-requested-line-rectangle described above except that it is 
/expanded/ in the before and after directions by an amount equal to the 
half leading of the containing block area. [If this half leading is 
negative, it will be contracted rather than expanded.]

The *expanded-rectangle* of an inline area child of a line area is the 
same as its allocation-rectangle described (under max-height strategy) 
above except that it is /expanded/ in the before and after directions by 
either (1) an amount equal to the half leading of the inline area, if 
generated by a non-replaceable element, or (2) amounts equal to the 
margin-{top,bottom} (or space-{before,after}), respectively, of the 
inline area, if generated by a replaceable element.

Because the half-leading of the containing block is already taken into 
account by the expanded-nominal-requested-line-rectangle, the 
space-before and space-after traits of each line area are set to zero.

This strategy corresponds to the line stacking strategy adopted by CSS, 
and is adopted by TTML, Section 9.3.3, step (5), when mapping 
intermediate synchronic documents to XSL-FO [6].

[6] 
https://dvcs.w3.org/hg/ttml/raw-file/default/ttml1/spec/ttml1.html#semantics-region-layout-step-2

As mentioned above, however, TTML1 does not presently apply line-height 
to inline elements (span or br), and thus the half-leading of each 
inline element is zero, and does not support a replaceable element type. 
Consequently, the line-height strategy, when applied to TTML1, produces 
equivalent results as produced by the max-height strategy. That is, each 
per-inline-height-rectangle is the same height as the equivalent 
maximum-line-rectangle to which half-leading (of the block) has been 
added (instead of applying this half-leading to the space-{before,after} 
of the line area).

So, with TTML1, this produces line areas that abut one another in the 
block progression dimension, but whose height includes half leading both 
before and after, as contrasted with max-height, where line areas don't 
abut but rather use space before and after on line areas to represent 
half leading.

    [XSL 4.5]

    The per-inline-height-rectangle for a line-area is the rectangle
    whose start-edge and end-edge are parallel to and coincident with
    the start-edge and end-edge of the nominal-requested-line-rectangle,
    and whose extent in the block-progression-dimension is determined as
    follows.

    ….

    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; this may vary depending on the descendants of the line-area.

    ….

    The expanded-rectangle of an inline-area is the rectangle with
    start-edge and end-edge coincident with those of its
    allocation-rectangle, and whose before-edge and after-edge are
    outside those of its allocation-rectangle by a distance equal to
    either (a.) the half-leading, when the area's allocation-rectangle
    is specified to be the normal-allocation-rectangle by the
    description of the generating formatting object , or (b.) the
    space-before and space after (respectively), when the area's
    allocation-rectangle is specified to be the large-allocation-rectangle.

    …..

    The expanded-nominal-requested-line-rectangle is the rectangle with
    start-edge andend-edge coincident with those of the
    nominal-requested-line-rectangle, and whose before-edge and
    after-edge are outside those of the nominal-requested-line-rectangle
    by a distance equal to the half-leading.

    ……

    The nominal-requested-line-rectangle for a line-area is the
    rectangle whose start-edge is parallel to the start-edge of the
    content-rectangle of the nearest ancestor reference-area and offset
    from it by the sum of the start-indent and the
    start-intrusion-adjustment of the line area, whose end-edge is
    parallel to the end-edge of the content-rectangle of the nearest
    ancestor reference-area and offset from it by the sum of the
    end-indent and the end-intrusion-adjustment of the line area, whose
    before-edge is separated from the baseline-start-point by the
    text-altitude of the parent block-area, and whose after-edge is
    separated from the baseline-start-point by the text-depth of the
    parent block-area. It has the same block-progression-dimension for
    each line-area child of a block-area.

    …

    [XSL 6.5.2]

    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 properties. The .precedence and
    .conditionality components are copied from the line-height property.

    CONCLUSION: Therefore lineHeight for each line of text in a TTML
    document is given by: largest fontSize on the line + half leading ==
    1.5 * largest fontSize

First, we must distinguish between the height of a line area and the 
computed value of the lineHeight property on an element. Here, you use 
the term "lineHeight", so I'm not sure to which of these you are referring.

As I indicated above, the computed value of the 'normal' lineHeight 
property value is derived from the maximum font size over the entire set 
of descendants of a paragraph element (in a particular intermediate 
synchronic document). Or, if the lineHeight property is specified as a 
length, then that is resolved as usual (without reference to any 
descendant element's font size).

Once the computed lineHeight value is resolved, now you can compute half 
leading and then derive individual line area rectangle heights according 
to the line stacking strategy rules.

So, if I were to state the correct conclusion, it would read:

*CONCLUSION: In TTML1, the height of a line area rectangle generated by 
a paragraph (<p/>) element is the greater of (a) the computed value of 
the lineHeight property that applies to the paragraph and (b) the sum of 
the maximum altitude and maximum depth of each font that applies to the 
line area's child inline areas.*

For those that wish to delve even deeper, I'd suggest reading:

[7] https://lists.w3.org/Archives/Member/w3c-xsl-fo-sg/2000Nov/0027.html 
(Member Only)
[8] http://meyerweb.com/eric/css/inline-format.html

Regarding [7], I'll check with the author to see if he minds me 
resending his message to this public list.

G.

-- 
------------------------------------------------
Andreas Tai
Production Systems Television IRT - Institut fuer Rundfunktechnik GmbH
R&D Institute of ARD, ZDF, DRadio, ORF and SRG/SSR
Floriansmuehlstrasse 60, D-80939 Munich, Germany

Phone: +49 89 32399-389 | Fax: +49 89 32399-200
http: www.irt.de | Email: tai@irt.de
------------------------------------------------

registration court&  managing director:
Munich Commercial, RegNo. B 5191
Dr. Klaus Illgner-Fehns
------------------------------------------------

Received on Friday, 23 August 2013 14:08:08 UTC