Hi,
I took a quick stroll through the code, and now I'm really getting the
impression that implementing indefinite page-width or page-height isn't
all that hard to achieve.
(Those enlightenments by Jeremias and Manuel yesterday sure gave me the
kick that was needed to grasp what happens and why our current
layout-engine is so darn' cool :-) )
The remark about running into a limitation WRT using int and
millipoints, which definitely did put a smile on my face :-), doesn't
seem to pose a problem, since the Integer.MAX_VALUE won't actually be
used anywhere for measurements --just as a hint to the
BreakingAlgorithm that there is no constraint on the page's height or
width. Explicit breaks are still possible. Luca was very right in
pointing out that the breaking algorithm can't be ignored.
Running out of memory is indeed the more likely result, but my guess is
that these properties weren't meant to be used to generate one
outrageously looooooong page. They do come in handy if you want to make
a nice electronic photo-album PDF, where each page doesn't necessarily
have to have the exact same dimensions --implementing "auto" for
page-width and -height is also a must if you don't want to end up with
pages that are all 8in wide or 11in high.
If the user forgot explicit breaks, then that's his concern --on a JVM
with sufficiently large heap-size, he will surely curse himself when he
first has to wait a couple of minutes only to realize that FOP crashes
and didn't get to render *any* content :-)
I'm definitely going to take a closer look soon, but right now I'll
just add a few comments for future reference (in case I don't get
around to it, someone else doesn't need to start from scratch)
Things to do (first glance):
1) In the properties package we should already catch the case of both
height and width being specified as "indefinite", and letting the other
default to "auto" (or the fallback: 11in or 8in), plus give a warning
about this. Rough idea: use a PageDimensionMaker extending
LengthProperty.Maker to deal with that --checks for the values of
reference-orientation and writing-mode could also be added here (cfr.
Rec 7.25.13 dependency on 'block-progression-direction')
2) In the area package, PageViewport currently sets the pageHeight and
pageWidth unconditionally to the integer value of the respective Length
instance variables of its SimplePageMaster. This should be changed to,
say a default of -1 or zero in case of getEnum() == EN_INDEFINITE (?),
since negative or zero values for page-height or -width make no sense
(at least not to me, but the 1.0 Rec doesn't seem to enforce a positive
non-zero value? [*]).
Also, probably something like a setPageHeight() method should be added
that allows the PageSequenceLM to feed the accumulated content-height
or -width back into the PageViewport after the BreakingAlgorithm has
done its work.
3) Similar remark as above for area.Page, which creates a FODimension
unconditionally using the height and width integer values.
4) Should code be added to FODimension itself for dealing with the
value indicating indefinite page-size? Might be better to subclass
FODimension... I'm not sure yet. I guess not creating a FODimension at
all would lead to NPE's being thrown.
That's it for now. AFAICT, the BreakingAlgorithm as it currently works,
requires only minimal modification to handle the rest without any
problems.
See what I mean: almost no changes to the layout-engine are needed --at
most, use Integer.MAX_VALUE in PageSequenceLM.getAvailableBPD() if the
BPD returned by the viewports turns out to be -1 or zero, and force the
current PageViewport's height/width in a break-situation. Come to think
of it, the first can most likely be handled by the viewports
themselves.
Cool!
Cheers,
Andreas
[*] BTW: currently, if the height/width is explicitly set to a negative
value, you get no real warning about this, but it does have its impact
on the result... It can always happen, I guess, especially when the
input FO comes from a complex XSL transformation, so it may be
worthwhile to provide a reasonable fallback in those cases. For
negative values, maybe we could flip the sign, for zero values the
currently used fallbacks (8 or 11in) should be sufficient. This could
be handled in the properties package without any problem.