Affects Version/s: trunk
Fix Version/s: None
Environment:Operating System: All
External issue ID:46905
At the moment no distinction is made between keep.within-column and keep.within-page. I've started to hack support for keep.within-column into the Trunk but don't have time to finish the task. Posting my changes here as a patch so that anyone who's interested can take over the job.
The idea is to make use of the break class of KnuthPenalty (which then becomes a 'keep context'). A keep.within-page will lead to an infinite penalty of class Constants.EN_PAGE. When a break is being considered, the break class will hint at whether it is allowed or not. For example, if the break is not at the last column of the page and the break class is page, the break may be considered.
At some point the breaking algorithm will run out of nodes because of forbidden page breaks that make the content pile up on the last column of a page. When such a situation is detected, the whole content is deferred to the next page (if that hasn't been already done) and column breaking is re-started. The hope is that a new, blank page will provide enough space to make all the content fit on one page. If it's still not the case, then the page break prohibition will be relieved to allow the content to flow to the next page.
- keeps have been implemented such that a keep.within-line implies a keep.within-column, which implies a keep.within-page. This is almost always true except if, for example, keep.within-page is set to always and keep.within-column to an integer value. The integer value from the column component will override the always value from the page component, possibly leading to an 'illegal' page break.
- some javadoc must be updated
- there are 10 failing test cases in the test suite
- at the moment no warning is issued when the content is too big to fit on one page alone
- in PageBreakingAlgorithm, the deferred and overridePageKeep fields need to be reset 'at the right moment'
- the overridePageKeep mechanism should actually be completely removed; if there's too much content to fit on a page then the usual overflow mechanism should be used instead. I initially set it up because the algorithm was reverting to starting the content on the same page instead of a new blank page. This needs to be investigated
- the new deferring mechanism clashes with fitRecoveryCounter; both should be merged somehow
- the deferring mechanism may also conflict with regular node recovery (restarting from the last deactivated/too short/too long node when the number of active nodes falls to zero). See commented out code in BreakingAlgorithm. It's not clear yet what may happen when.
- the use of break class from KnuthPenalty is very hacky and a new characteristic should probably be defined. Using an infinite penalty with a tweaked break class leads to too many changes at too many places. Maybe it can be done the other way round: use a zero penalty with break class properly set to indicate when this penalty must be considered as infinite (or infinite - 1).
- at the moment penalties are discarded at page breaks until the end of the keep.within-column zone has been reached. At that point the content may already have been overflowing the last column for a long time. This might lead to performance issues.