You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by Apache Wiki <wi...@apache.org> on 2005/04/18 18:53:29 UTC

[Xmlgraphics-fop Wiki] Update of "MultiLayoutSequence" by LucaFurini

Dear Wiki user,

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

The following page has been changed by LucaFurini:
http://wiki.apache.org/xmlgraphics-fop/MultiLayoutSequence

The comment on the change is:
Creation of the sequence for a multi-layout paragraph

New page:
With a single paragraph layout, the sequence of elements contains only boxes and zero-length penalties. Multi-layout sequences will contain glues too, so they will be able to stretch and shrink.

= Parameters =

The parameters involved are:
 * the minimum, optimum and maximum quantities of lines generated by the paragraph; they can be referred to either using '''min''', '''opt''' and '''max''', or using the syntax '''opt'''(-'''m''',+'''p''') where '''m''' is ('''opt''' - '''min''') and '''p''' is ('''max''' - '''opt''')
 * the values of the widows and orphans properties, which will be referred to using '''w''' and '''o''' respectively.

= Possible situations =

A line layout allows the paragraph to be split between consecutive pages only if it has more than ('''w''' + '''o''') lines.

According to the relative position of the value ('''w''' + '''o''') and '''min''', '''opt''' and '''max''', we can have four different situations:

 1. ('''w''' + '''o''') <= '''min'''
 1. '''min''' < ('''w''' + '''o''') <= '''opt'''
 1. '''opt''' < ('''w''' + '''o''') <= '''max'''
 1. '''max''' < ('''w''' + '''o''')

{{{
         min   opt        max
   -------+-----+----------+-------
     ^          ^     ^          ^
     |          |     |          |
    w+o        w+o   w+o        w+o
    (1)        (2)   (3)        (4)
}}}

== (w + o) <= min ==

This is a simple case: even the layout with fewest lines allows the paragraph to be split.

The first '''o''' lines and the last '''w''' lines cannot be parted because of the orphans and widows properties; between these two groups there are other '''opt'''-'''o'''-'''w'''(-'''m''',+'''p''') lines, and each one can be preceded or followed by a page break. These lines can be divided into three categories:

 * "optional lines": they can be used, if needed, in order to occupy a greater space
 * "eliminable lines": they can be omitted, if needed, in order to occupy a smaller space
 * "inner lines": normal lines

Note that, when we have more than a single layout, the elements in the sequence will not represent a "real" line (for example, the line starting at the 12th word and ending after the 16th one): they are only "place holders". So, adding or omitting a line does not mean that we are adding or omitting some content; it means that we have to increase or reduce text spacing so that the same content will generate more or fewer lines.

In particular, there are:
 * '''o''' first lines
 * ('''max''' - '''opt''') optional lines
 * ('''opt''' - '''min''') eliminable lines
 * ('''min''' - ('''o''' + '''w''')) inner lines
 * '''w''' last lines

The mapping between lines and elements is quite simple:
 * first, inner and last lines are represented by a single box with appropriate length;
 * optional lines are represented by the sub-sequence {{{box(0) penalty(0, inf) glue(0, 1, 0) box(0)}}} whose length is in the range [0, 1], unadjusted length = 0;
 * eliminable lines are represented by the sub-sequence {{{box(1) penalty(0, inf) glue(0, 0, 1) box(0)}}} whose length is in the range [0, 1], unadjusted length = 1;
 * these sub-sequences are divided by a {{{penalty(0, 0)}}}.

== min < (w + o) <= opt ==

This is a more complex situation: with the optimal quantity of lines (or with a greater one) the paragraph can be parted, while the minimal quantity of lines does not allow a break.

In other words, the whole sequence will have an overall shrink of '''opt''' - '''min''', but a break will reduce the total shrink to '''opt''' - ('''o''' + '''w''').

There is a new category of lines, "conditional eliminable lines": they can be omitted, but only if the paragraph is not parted.

There are:
 * (('''o''' + '''w''') - '''min''') conditional eliminable lines
 * '''o''' first lines
 * ('''max''' - '''opt''') optional lines
 * ('''opt''' - ('''o''' + '''w''')) eliminable lines
 * '''w''' last lines

The mapping between lines and elements is exactly like before, with two changes:
 * the first lines are represented by {{{box(o) penalty(0, inf) glue(0, 0, ((o + w) - min)) box(0)}}} instead of a single {{{box(o)}}};
 * the breaker between the sub-sequences is {{{penalty(0, inf) glue(0, 0, -((o + w) - min)) penalty(0, 0) glue(0, 0, ((o + w) - min))}}} instead of a {{{penalty(0, 0)}}}.

The overall effect of the glue elements in the breaker is {{{glue(0, 0, 0)}}}: if the paragraph is not parted, they don't modify the available shrink; if the paragraph is parted, the first glue "cancels" the one in the first lines, while the second one is suppressed.

== opt < (w + o) <= max ==

The optimal quantity of lines (and obviously a smaller one) does not allow the paragraph to be parted, while the maximal one does.

In other words, parting the paragraph involves an increase in the quantity of lines.

There is a new category of lines, "conditional optional lines": they can be used if the paragraph is not parted, while they must be used if the paragraph is parted.

There are:
 * ('''opt''' - '''min''') conditional eliminable lines
 * (('''o''' + '''w''') - '''opt''') conditional optional lines
 * '''o''' - (('''o''' + '''w''') - '''opt''') first lines
 * ('''max''' - ('''o''' + '''w''')) optional lines
 * '''w''' last lines

The mapping between lines and elements is almost like before, with two changes:
 * the first lines are represented by {{{box(opt - w) penalty(0, inf) glue(0, ((o + w) - opt), (opt - min)) box(0)}}}}}};
 * the breaker between the sub-sequences is {{{penalty(0, inf) glue(0, -((o + w) - opt), -(opt - min)) penalty(((o + w) - opt), 0) glue(0, ((o + w) - opt), (opt - min))}}}.

== max < (w + o) ==

This is the simplest case: the lines can never be parted, regardless of the line layout.

The whole paragraph is represented by the sequence {{{box(opt) penalty(0, inf) glue(0, max - opt, opt - min) box(0)}}}.

= Limitations =

The sequence created is correct if every line has the same height, which is undoubtedly the most common situation. Note that it is likely that a document with lots of inline content with different font sizes will not have display-align="fill", and anyway the filling could be achieved modifying other properties, for example spaces between blocks.

The algorithm could be easily modified in order to recognize and handle correctly even multi-layout paragraphs with lines having a different height (for example, because of inline content with a bigger font size), if these abnormal lines are always in the group of the first (or last) ones. For example, paragraphs starting with a big letter does not create serious problems, as it is enough to set the right height in the first box of the sequence.

Some more thought is needed in order to handle correctly a multi-layout paragraph with abnormal inline content in its middle, whose position depends on the line layout (for example, the inline object could be in the 4th or in the 5th line, according to the text spacing).

Note that these problematic situations can be easily recognized, and normally handled choosing the best layout: i.e. we can always, as a fallback, ignore alternative layouts with fewer or more lines.

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