Part of the line building process is the correct alignment of inline children of a line area. The rules and properties governing this process are described in various places in the XSL-FO specification. In particular section 4.6 and section 7.13 are relevant. However there are a number of open, unclear or User Agent specific areas in the specification and this page attempts to document to approach taken by FOP in those cases.
The specification assumes the existence of baseline tables in the font definitions. However, most common fonts formats, especially True Type and PFM, do not carry this information. For these fonts FOP needs to calculate the various baselines based on the basic font information which consists of the ascender height, the descender depth and the x height. These fonts are all assumed to have their alignment point on the alphabetic baseline, that is the 3 values mentioned are given relative to the fonts alphabetic baseline. This seems to be true even for non Western scripts as inspection of some sample font files for scripts that would be expected to use ideographic and hanging baselines shows. FOP uses these simple formulas to calculate the position of the following baselines relative to the alphabetic baseline:
ideographic = descender depth
- alphabetic = 0
central = (ascender height - descender depth) / 2
middle = x height / 2
text-after-edge = descender depth
text-before-edge = ascender height
Hanging and mathematical baselines
There are no obvious formulas to calculate the position of these baselines. At the time of writing FOP puts the hanging baseline at 80% of the ascender height and the mathematical baseline at 50%.
NOTE: It may be desirable to have this configurable in the user configuration or be able to set these baseline values in the font configuration.
before-edge and after-edge baselines
These are not baselines defined in a font but computed baselines. According to the spec these baselines are only defined for line areas. However, any alignment between two areas is done by aligning the alignment baseline of the parent area with the matching alignment point of the child area. That alignment point is defined as the intersection of the corresponding baseline with the start-edge. This will only work for the before-edge and after-edge alignment baselines if these baselines are defined on the child area to be aligned. FOP therefore takes the approach that the before-edge and after-edge baselines for inline areas coincide with the before and after edges of the allocation rectangles of the inline area. For most inline areas these are identical to the text-before-edge and text-after-edge baselines.
Baselines for areas generated from external-graphic and inline-foreign-object
For these areas we cannot use font data to calculate the baseline positions. FOP treats these areas as if they are defined using a font with ascender height == height of area, descender depth == 0 and x height == ascender height and then uses the same formulas as above.
Baseline co-ordinate systems and scaling
Internally FOP implements directly only the scaled-baseline-table. This is partly because the font system delivers all font data already scaled to the font size. The origin is always the position of the dominant-baseline as identified by the dominant-baseline-identifier. Positive baseline values are from the dominant-baseline towards the before-edge.
FOP defines a ScaledBaselineTable interface, a ScaledBaselineTableFactory and (at the time of writing) a single implementation of the interface, the BasicScaledBaselineTable. All of those are contained within the layoutmgr.inline package. This architecture should allow to easily add other baseline table implementations, especially for fonts which contain baseline information, e.g. Open Type, at a later date.
Baselines for vertical writing modes
While the interfaces defined do support baseline table construction for different writing modes the current implemenation supports horizontal writing modes only.
The spec leaves a number of issues unclear with respect to baseline shifts.
Baseline shift and a change of dominant baseline
When a baseline shift is combined with a change of the dominant baseline it is unclear if the shift is applied first and then the new baseline table calculated or if the new baseline table is calculated first and then the shift applied. Here is an example:
Some text <fo:inline font-size=".5em" dominant-baseline="hanging" baseline-shift=".25em">small and up </fo:inline>
Is the ".25em" shift between the alphabetic baseline of the parent and the alphabetic baseline of the child or the hanging baseline of the child? FOP takes the view that a baseline-shift first moves the dominant baseline and then establishes the new dominant baseline.
Implicit baseline shifts when rescaling
When a baseline table is rescaled an implicit baseline shift can happen a situation the spec appears to ignore. Take this example:
Some text <fo:inline font-size=".5em" alignment-baseline="central" dominant-baseline="reset-size">small and up </fo:inline>
Because the alignment baseline is different to the dominant baseline and the baseline table gets rescaled we have an implict shift of the dominant baseline. The above example is logically equivalent to:
Some text <fo:inline font-size=".5em" baseline-shift="xxx">small and up </fo:inline>
with "xxx" being the shift amount required to align the "central" baselines. FOP calculates and maintains these implict baseline shifts.
Subscripts and Superscripts
Sub and Super scripts are special forms of baseline shifts. The spec implies that each font has a subscript and a superscript shift amount. However, that is only true for some of the font formats supported by FOP. In addition the current FOP font interface does not expose that information (even if it is present in the underlying font). Initial tests with using a fixed shift factor for superscripts and subscripts (different factor for super and sub though) appear to give unsatisfactory results especially if different font sizes are involved between the main element and the subscript element. Some further testing with CSS and browsers seem to indicate that they take both font sizes into account. Therefore FOP at the time of wrting uses the following method to determine the shift values: Assuming the dominant baseline is alphabetic a superscript element is aligned such that its alphabetic baseline coincides with the x height of the parent, that is a superscript "starts" at the top of the lowercase "x", i.e. similar but not identical to "x2". Assuming the dominant baseline is alphabetic a subscript element is aligned such that its middle baseline aligns with the parents alphabetic baseline, that for a subscript character "x" the middle of "x" aligns with the alphabetic baseline of the parent, i.e. similar but not identical to "2x". There may be further fine tuning required to achieve visually more appealing results, e.g. both superscripts and subscripts may have to be lowered a fraction.
Observation: If one views this page using Mozilla Firefox the sub/superscripts examples in the paragraph above render nearly exactly as FOP currently does it. In IE the same sub/superscripts are put in different positions.
NOTE: It may be desirable to have this configurable in the user configuration or be able to set these values in the font configuration.
With respect to line areas there can be conflicting or overconstraint alignment specifications. I couldn't find a reference to that situation in the specification. Example:
<fo:block font-size="32pt">Big <fo:inline font-size=".25em" dominant-baseline="reset-size" alignment-baseline="before-edge">top <fo:inline font-size="2em">alpha </fo:inline> </fo:inline> </fo:block>
Here we want "top" at the before-edge of the line area but the nested inline "alpha" wants to be aligned at the alphabetic baseline of "top". Because "alpha" uses a bigger font than "top" these two conditions cannot be satisfied simultaneously. It is unclear how this is to be resolved.