Keep-with-next handling

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Keep-with-next handling

Jeremias Maerki
Gang,

I'm currently working on keeps. As you might have seen, I've found a
little problem concerning keep-with-next even on blocks. I've already
fixed it locally, but I am not quite ready to commit, yet, since I want
to get be sure first that my approach pays off (but it seems that way).
Here's what I changed:

Until now, the LMs kept track of the previous LM and created an infinite
penalty if a keep-with-next situation presented itself. This ignores the
fact, however, that lower-level FOs can have a keep-with-next that
influences a following FO on a higher level (see keep-with-next1a). I
solved it by introducing a flag (KEEP_WITH_NEXT_PENDING) on the
LayoutContext which will be propagated up the LM hierarchy. The next LM
in charge of adding a penalty will check for that flag on the
LayoutContext. That even made keep-with-next on tables very easy. It
already works locally.

What remains is to implement keep-with-previous on tables and then
spread the new approach for keep-with-next to the rest of the LMs. I'm
keeping the keeps strictly boolean for now which should cover >95% of
the use cases in reality. Later we will need to refine the handling to
distinguish between the two contexts (column/page) and strengths.

JFYI

Jeremias Maerki

Reply | Threaded
Open this post in threaded view
|

Re: Keep-with-next handling

Luca Furini
Jeremias Maerki wrote:

> Until now, the LMs kept track of the previous LM and created an infinite
> penalty if a keep-with-next situation presented itself. This ignores the
> fact, however, that lower-level FOs can have a keep-with-next that
> influences a following FO on a higher level (see keep-with-next1a). I
> solved it by introducing a flag (KEEP_WITH_NEXT_PENDING) on the
> LayoutContext which will be propagated up the LM hierarchy. The next LM
> in charge of adding a penalty will check for that flag on the
> LayoutContext. That even made keep-with-next on tables very easy. It
> already works locally.

If it works, I think it's good! :-)

I have thought of an alternative approach (but I did not try and implement
it, so it's just an abstact idea that could be completely wrong): the
methods mustKeepWithPrevious() and mustKeepWithNext(), that at the moment
only check the properties of their node, could call the same method on the
relevant child.

So, for example, BlockLM.mustKeepWithPrevious() could be:
    return !getBlockFO().getKeepWithPrevious().getWithinPage().isAuto()
        || !getBlockFO().getKeepWithPrevious().getWithinColumn().isAuto())
        || firstChild.mustKeepWithPrevious();

and BlockLM.mustKeepWithNext()
    return !getBlockFO().getKeepWithNext().getWithinPage().isAuto()
        || !getBlockFO().getKeepWithNext().getWithinColumn().isAuto()
        || lastChild.mustKeeptWithNext();

Regards
    Luca



Reply | Threaded
Open this post in threaded view
|

Re: Keep-with-next handling

Jeremias Maerki

On 24.05.2005 18:43:42 Luca Furini wrote:

> Jeremias Maerki wrote:
>
> > Until now, the LMs kept track of the previous LM and created an infinite
> > penalty if a keep-with-next situation presented itself. This ignores the
> > fact, however, that lower-level FOs can have a keep-with-next that
> > influences a following FO on a higher level (see keep-with-next1a). I
> > solved it by introducing a flag (KEEP_WITH_NEXT_PENDING) on the
> > LayoutContext which will be propagated up the LM hierarchy. The next LM
> > in charge of adding a penalty will check for that flag on the
> > LayoutContext. That even made keep-with-next on tables very easy. It
> > already works locally.
>
> If it works, I think it's good! :-)
>
> I have thought of an alternative approach (but I did not try and implement
> it, so it's just an abstact idea that could be completely wrong): the
> methods mustKeepWithPrevious() and mustKeepWithNext(), that at the moment
> only check the properties of their node, could call the same method on the
> relevant child.
>
> So, for example, BlockLM.mustKeepWithPrevious() could be:
>     return !getBlockFO().getKeepWithPrevious().getWithinPage().isAuto()
>         || !getBlockFO().getKeepWithPrevious().getWithinColumn().isAuto())
>         || firstChild.mustKeepWithPrevious();
>
> and BlockLM.mustKeepWithNext()
>     return !getBlockFO().getKeepWithNext().getWithinPage().isAuto()
>         || !getBlockFO().getKeepWithNext().getWithinColumn().isAuto()
>         || lastChild.mustKeeptWithNext();

Could work for most cases although it would probably be difficult again
on tables and a little less so on lists. I had to do some special stuff
on tables and have still not solved everything. For example:

+---------------+----------------+
| cell1 line1   | cell2 line1    |
|               | cell2 line2    |
+---------------+----------------+
| cell3 line1   | cell4 line1    |
+---------------+----------------+

A keep-with-previous on the second row should create a "glue" (not a
knuth glue) not only between cell2 line2 and cell4 line1 but also
between cell2 line1 and cell3 line1. This means that in the combined
element list you get multiple infinite penalties. Your alternative
approach might really help here. But I keep coming to the conclusion
that I might have to get the cell content element lists of the following
row (group) before I can finish the combined element list for the
current one (because you might have a keep-with-previous in there).

Jeremias Maerki