On Aug 23, 2006, at 21:16, Patrick Paul wrote:
Simon Pepping wrote:
On Tue, Aug 22, 2006 at 11:35:12PM +0200, Andreas L Delmelle wrote:
I don't know exactly what Adreas has in mind be we actually need
this for the auto-table layout.
I've been doing some thinking myself about the separation
between element-list creation and actual line-breaking, and went
wandering through the related sources. Just checking here if my
initial estimates are correct.
Which problem are you trying to solve? Paragraph layout where the
width changes in the paragraph?
Simon's correct. I'll clarify a bit more. From what I could tell,
Patrick's patch has added code at the right places, it only seems a
bit awkward to me to import stuff related to table-layout into the
LineLayoutManager (even if it is nothing more than a TableHelper).
(Note: this part was not wrong per se in the patch. It just seems
there currently is no other way, precisely because list-creation and
breaking are performed in the same method. The only place where it
can be entered is somewhere between those two statements --
collectInlineKnuthElements() and createLineBreaks().)
A more correct approach --a matter of taste?-- would be for the
TableContentLM to 'collect' the accumulated list of its descendant
LMs, perform the min/max-width calculation, update the LayoutContext,
and send it back down to the LineBreaker.
Maybe someone sees another approach that I'm overlooking?
The breaking algorithm needs to be given a LayoutContext with a
certain available amount of ipd. Since the base element list does not
depend on this amount --apart from the start- or end-of-paragraph
elements-- this means it should be feasible to separate the former
from the latter.
In auto-table layout, we have to take into account the possibility
that none of the column-widths are specified. Both minimum and
maximum depend on the content. Strictly speaking, apart from the
arbitrary default 'available ipd / # columns', you don't have a
correct ipd to give to the Breaker. If you do perform the breaking,
however, the element list will also contain elements that have been
added by the Breaker.
Although I haven't done too much investigation on whether they
influence the content-width calculation, this still means these
elements are created for no reason at all.
IOW: this would be a wasted trip through the breaking algorithm.
This may be possible, but it does not seem to be in the spirit of the
algorithm. The algorithm calculates the best layout up to the current
linebreak. You can always interrupt the calculation and resume later,
provided you keep the list of active nodes. If you want N lines, then
you do not determine in advance the end element. You proceed until you
have all active nodes that end line N, and then determine the best of
them. But it is even better to continue to the end of the paragraph,
taking the modified line width into account. That gives you the best
total-fit for the whole paragraph. In that total-fit, the layout for
the first N lines may be suboptimal, but then it is offset by a better
result for the remaining lines.
OK. This makes sense. I'm going to chew some more on this.
The other consideration, but that would be for a more distant future,
is to be able to have three different threads:
- fo creation
- base layoutengine initialization
- actual breaking/layout
Those could run in concert, so the layoutengine initialization does
not need to wait for the endPageSequence() event, but could already
be started much earlier. If it reaches a point where it makes sense
to start with the break computation, the third thread can be started.
Ultimately, this will end up running out of input, and control will
be returned to the second thread. If the second thread runs out of
FOs, it returns control to the first.
In theory, it then also becomes possible, for both a total-fit and
first-fit algorithm, to release certain FOs before the layout for the
entire page-sequence is finished.