xmlgraphics-fop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Xmlgraphics-fop Wiki] Update of "FootnotesAndBeforeFloats/Footnotes" by AndreasLDelmelle
Date Wed, 15 Jun 2011 16:54:16 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Xmlgraphics-fop Wiki" for change notification.

The "FootnotesAndBeforeFloats/Footnotes" page has been changed by AndreasLDelmelle:

New page:
''This page is a work-in-progress, and aims to serve as documentation of how FOP's layout
engine processes footnotes, mainly to save interested contributors the hassle of having to
find out the hard way...''
= Introduction =

[[http://www.w3.org/TR/xsl/|XSL-FO]] defines the {{{fo:footnote}}} formatting object to allow
authors to insert citations into their documents. 
These footnotes are attached to the line area in which they would appear, and are to be rendered
in a reserved footnote-area on the after-edge of the region-reference-area, preceded by a
footnote-separator if one is defined in the source.
This page intends to describe only the approach with respect to the layout engine. The initial
validation of out-of-line descendants during parsing is considered out of scope.

FOP's layout engine has to deal with footnote content in two phases (most general use case;
see further below for the special cases):
 * Line layout: the footnotes are attached to the box representing the line area that holds
the surrounding inline content in the source
 * Page layout: the footnotes are placed on the page that contains the line area that holds
the anchor

= Line layout =

During the initial collection of the inline {{{KnuthElements}}}, if footnotes are encountered,
a {{{KnuthInlineBox}}} is generated for the anchor, that holds a reference to the {{{FootnoteBodyLayoutManager}}}.
If the anchor is empty, a dummy auxiliary box will be inserted to make sure the footnote is
rendered at the appropriate place. (see: {{{org.apache.fop.layoutmgr.inline.FootnoteLayoutManager.getNextKnuthElements()}}})

The {{{LineLayoutManager}}} is responsible for making sure that the LMs for the footnote-bodies
are attached to the appropriate line box (see: {{{org.apache.fop.layoutmgr.inline.LineLayoutManager.postProcessLineBreaks()}}}).

== Special cases: lists and tables ==

As lists and tables 'aggregate' their content and return {{{KnuthBoxes}}} encompassing multiple
line areas, they (currently) have to take care of propagating the footnotes from the contained
line boxes upward, so that the {{{PageBreaker}}} will be able to access them. TODOs have been
left in the code, and concerns have been raised that the related classes should actually remain
footnote-agnostic. Ultimately, there is a certain duplication of what {{{LineLayoutManager}}}

One possible strategy to avoid that, would be to push this out of the LMs, and into a factory
that constructs boxes based on (lists of) element lists. All this logic would then be contained
in a single class. The LMs, instead of explicitly instantiating the boxes, would just pass
the sublist(s) that represent the contained content, and get back the appropriate type of
box to add to their element list.

see also: [[https://issues.apache.org/bugzilla/show_bug.cgi?id=37579|Bugzilla 37579]]

= Page layout =

== Initial pass - Layout of the footnote bodies ==

During an initial pass over the block list returned by the {{{FlowLayoutManager}}}, the {{{PageBreaker}}}
first triggers line layout of all the footnote-bodies, so that the footnotes' lists of line
boxes are directly accessible in the corresponding content boxes. The reason this was deferred
from line layout, is that the context will not always be the same. In case of multi-column
layout, the footnotes will span the whole region-reference-area, rather than follow the flow's

If footnotes were encountered, layout of the footnote-separator is done here, so that its
block-progression-dimension will be readily available when needed later by the {{{PageBreakingAlgorithm}}}.

see: {{{org.apache.fop.layoutmgr.PageBreaker.getNextKnuthElements()}}}

== Calculating the breaks ==

A (line) box with anchors triggers {{{PageBreakingAlgorithm.handleFootnotes()}}}, which:

 * adds the corresponding element lists to footnoteList
 * computes the total length of each of the element lists
 * for each element list, stores the accumulated length of all preceding notes plus its own,
in {{{lengthList}}}

Additionally, {{{totalFootnotesLength}}} is increased with the length of each footnote.

For all following legal breaks, this will result in {{{PageBreakingAlgorithm.computeDifference()}}}
taking into account the additional width required for the footnote separator and the footnotes
up to that point.
If the total length of content + separator + all footnotes does not fit within the available
width, and it is allowed to defer part of the footnotes to the following page, the footnote
length will be split here.

The chosen strategy is to:
 * first try adding all footnotes that can no longer be deferred (i.e. were already carried
over from a previous break)
 * then add whole footnotes, until we reach one that doesn't fit in its entirety
 * from the next footnote, try adding more parts, until we reach the part that doesn't fit

= Remaining Issues =

== Footnotes and multi-column flows ==

Since there is no hard distinction between page- and column-breaks, with respect to footnotes,
each column acts as its own page. The best node for each column is determined by only looking
at the footnotes whose anchors are in ''that'' particular column. This leads to overlaps between
footnotes and the flow content.

see: [[https://issues.apache.org/bugzilla/show_bug.cgi?id=51304|Bugzilla 51304]]

== Infinite loops in footnote deferral ==

There are currently multiple open Bugzilla reports about infinite loops being triggered under
certain circumstances. Closer inspection reveals that the culprit is the footnote deferral
mechanism, very likely in the interaction between {{{PageBreakingAlgorithm.getFootnoteSplit()}}}
and {{{.createFootnotePages()}}}. Certain assumptions are made in {{{getFootnoteSplit()}}}
that do not always seem to hold. One such assumption is that the local variable {{{splitLength}}}
will eventually always exceed the {{{availableLength}}}.

see: [[https://issues.apache.org/bugzilla/show_bug.cgi?id=47424|Bugzilla 47424]]
or [[https://issues.apache.org/bugzilla/show_bug.cgi?id=48397|Bugzilla 48397]]

== Space resolution between footnotes ==

When the {{{PageBreakingAlgorithm}}} adds a box's footnotes, space-resolution is triggered
for each footnote separately. This does not take into account potential stacking constraints
''between'' the footnotes.

see code comment in: {{{PageBreakingAlgorithm.handleFootnotes()}}}


To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org

View raw message