in fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java [698:816]
private void collectInlineKnuthElements(LayoutContext context) {
LayoutContext inlineLC = LayoutContext.copyOf(context);
// convert all the text in a sequence of paragraphs made
// of KnuthBox, KnuthGlue and KnuthPenalty objects
boolean previousIsBox = false;
StringBuffer trace = new StringBuffer("LineLM:");
Paragraph lastPar = null;
InlineLevelLayoutManager curLM;
while ((curLM = (InlineLevelLayoutManager) getChildLM()) != null) {
List<KnuthSequence> inlineElements = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
if (inlineElements == null || inlineElements.size() == 0) {
/* curLM.getNextKnuthElements() returned null or an empty list;
* this can happen if there is nothing more to layout,
* so just iterate once more to see if there are other children */
continue;
}
if (lastPar != null) {
KnuthSequence firstSeq = inlineElements.get(0);
// finish last paragraph before a new block sequence
if (!firstSeq.isInlineSequence()) {
lastPar.endParagraph();
ElementListObserver.observe(lastPar, "line", null);
lastPar = null;
if (log.isTraceEnabled()) {
trace.append(" ]");
}
previousIsBox = false;
}
// does the first element of the first paragraph add to an existing word?
if (lastPar != null) {
KnuthElement thisElement;
thisElement = (KnuthElement) firstSeq.get(0);
if (thisElement.isBox() && !thisElement.isAuxiliary()
&& previousIsBox) {
lastPar.addALetterSpace();
}
}
}
// loop over the KnuthSequences (and single KnuthElements) in returnedList
for (Object inlineElement : inlineElements) {
KnuthSequence sequence = (KnuthSequence) inlineElement;
// the sequence contains inline Knuth elements
if (sequence.isInlineSequence()) {
// look at the last element
ListElement lastElement = sequence.getLast();
assert lastElement != null;
previousIsBox = lastElement.isBox()
&& !((KnuthElement) lastElement).isAuxiliary()
&& ((KnuthElement) lastElement).getWidth() != 0;
// if last paragraph is open, add the new elements to the paragraph
// else this is the last paragraph
if (lastPar == null) {
lastPar = new Paragraph(this,
textAlignment, textAlignmentLast,
textIndent.getValue(this),
lastLineEndIndent.getValue(this));
lastPar.startSequence();
if (log.isTraceEnabled()) {
trace.append(" [");
}
} else {
if (log.isTraceEnabled()) {
trace.append(" +");
}
}
lastPar.addAll(sequence);
if (log.isTraceEnabled()) {
trace.append(" I");
}
// finish last paragraph if it was closed with a linefeed
if (lastElement.isPenalty()
&& ((KnuthPenalty) lastElement).getPenalty()
== -KnuthPenalty.INFINITE) {
// a penalty item whose value is -inf
// represents a preserved linefeed,
// which forces a line break
lastPar.removeLast();
if (!lastPar.containsBox()) {
//only a forced linefeed on this line
//-> compensate with an auxiliary glue
lastPar.add(new KnuthGlue(ipd, 0, ipd, null, true));
}
lastPar.endParagraph();
ElementListObserver.observe(lastPar, "line", null);
lastPar = null;
if (log.isTraceEnabled()) {
trace.append(" ]");
}
previousIsBox = false;
}
} else { // the sequence is a block sequence
// the positions will be wrapped with this LM in postProcessLineBreaks
knuthParagraphs.add(sequence);
if (log.isTraceEnabled()) {
trace.append(" B");
}
}
} // end of loop over returnedList
}
if (lastPar != null) {
lastPar.endParagraph();
ElementListObserver.observe(lastPar, "line", fobj.getId());
if (log.isTraceEnabled()) {
trace.append(" ]");
}
}
log.trace(trace);
}