-----BEGIN PGP SIGNED MESSAGE-----
First of all: many, many thanks to Finn for taking care of the default
Secondly: sorry for the rather long post.
This message is solely intended to keep you guys (and other interested
parties) informed about my progress in this matter, and perhaps, more
importantly, to give other devs the opportunity to yell 'STOP!' if
they see something that could be considered a Very Bad Thing (as Java
programming is still a leisure activity for me, it's all based on
theory rather than hands-on experience).
Ok, here goes:
* The first step I took was moving much of the logic that is currently
in CollapsingBorderModelEyeCatching (in the layout package) to
More precisely: I created a subclass of the BorderInfo inner class.
This subclass, TableBorderInfo, provides two versions of a collapse()
method: one for eye-catching collapsing, and an overloaded one that
allows for passing in precedence values. Their signatures are:
public void collapse( BorderInfo, boolean );
public void collapse( BorderInfo, boolean, int, int );
The idea here is to make this functionality available to the FOTree as
well as Layout without moving essentially layout-related code into the
FOTree (or vice versa). I'm not absolutely sure that subclassing
BorderInfo is the appropriate approach, since the collapse() methods
could just as easily be added to BorderInfo itself. Personally, I did
this to make the distinction, as those methods do not apply to borders
on non-table FOs (but in the end, the other FOs simply won't call this
method, so there would be little harm in that).
In any case, the ultimate goal is to have layout only access the
collapse() methods for the situations where the FOTree lacks the
necessary context. The most obvious ones: breaks, spans and multiple
But for a simple table with one body that has no row- or
column-spanning cells and that is small enough to fit on one page,
layout would only read the border-info from the FOs appropriate for the
given situation. The layout classes will still need to decide which FO
is the appropriate one, but once that decision has been made, all they
need to do is read the border-info and use the width (no additional
The collapse-method does not need to concern itself with which sides
the borders are on, as this depends on the types of FO the borders
belong to. (For example: when comparing header and body, the header's
after-border needs to be compared to the body's before-border, but when
comparing header and table, the pair is before/before) All it does is
compare its BorderInfo instance to another that is being passed in, and
modify the style/width/color values if and where necessary. The 'side'
issue should be dealt with at another level.
The primary function of the boolean parameter is to allow/prohibit the
property values to be replaced by those of the BorderInfo that is being
passed in as a parameter. If the parameter BorderInfo wins, it simply
keeps its own set of values, and depending on this flag, forces these
values onto the base BorderInfo for which collapse() was called. If the
parameter BorderInfo loses, its values are *always* discarded and
replaced. The boolean flag comes in handy, for example when
Table.omitHeaderAtBreak() is true. When resolving border-conflicts
between header and body, the body's border cannot be discarded/replaced
since it could still be relevant for all but the first page (or column)
that is spanned by the table.
This first step is as good as complete in my local sandbox.
[As a side-note: I'm also thinking of providing two getCollapsed()
methods that return the winning BorderInfo instance instead of actually
replacing one with the other. This might come in handy when the table
has more than one body, and may also prove useful for the
layout-classes, since it's not always desirable to actually change the
* I added a class named TableBorderConflictResolver to the fo.flow
package. One of these will be instantiated for/enclosed by each Table
instance that doesn't have separated borders. This class is currently
under heavy construction, so I can't offer a lot of details yet.
The main idea here is to provide a set of overloaded versions of a
resolve() method that resolves the border-conflicts between the
enclosing Table instance and its descendants (one parameter) or between
two of the Table's descendants (two parameters). These methods are the
ones that will sort out the 'sides' issue. They will call
TableBorderInfo.collapse() for each pair of applicable sides
(start/start, end/end, before/before, after/before etc.)
* Evidently, Table then needs to allow its descendants to use the
TableBorderConflictResolver. I don't think this access needs to be
public, as the layout-classes have access to the FOs BorderInfo, so
they can call collapse() (or possibly getCollapsed()) directly when
they need to.
Other ideas are still a bit too remote/vague for me to able to give an
accurate description of them. I roughly see the resolving taking place
in two phases: once before the FOEventHandler.startXXX() is fired, and
once immediately before the endXXX() event. Those two phases each will
consist of two stages:
- - the first stage, called from TableBody/TableHeader/TableFooter,
resolves border conflicts between
Table/TableHeader/TableFooter/TableBody (and maybe TableColumn), so
could be described as working downwards/inwards
- - the second stage, called from TableCell, resolves the conflicts
between TableCells/TableRow/TableColumn/TableBody, so works
That's it for now. Probably more to follow during or after the weekend.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)
-----END PGP SIGNATURE-----