[ https://issues.apache.org/jira/browse/FOP-2809?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16924243#comment-16924243 ]
Dan Caprioara commented on FOP-2809: ------------------------------------ Possible fix in the LineLayoutManager. Add these methods: {code:java} /** * <p> * The collectInlineKnuthElements method creates some paragraphs based on the assumption that * the child layout managers (that can be one ore more TextLayoutManager or InlineLayoutManagers) * are returning a KnuthSequence for each line. By line is understood a sequence ending in a new line. * In the Knuth terms, a forced line break is represented by an auxiliary box with a negative infinite penalty . * </p> * <p> * The assuption proved false when a block like: * <pre> * <inline> * alpha <inline>beta</inline> * <inline>gamma</inline> * </inline> * </pre> * was broken into: * <pre> * <inline> * alpha * <inline>beta</inline> * <inline>gamma</inline> * </inline> * </pre> * because the LineLayoutManager had a single child * InlineLayoutManager, that concatenated all the subtree LM boxes into a single sequence. * The {@link LineLayoutManager#collectInlineKnuthElements(LayoutContext)} is looking for line breaks only at the end of sequences, and * misses the newlines from the middle of the preformatted text. * </p> * <p>The solution is to pre-process each of the sequences and split it if it is the case. * * * * @param inlineElements The list of sequences, each representing a line. Each of the sequence will be analysed and split into multiple ones if a hard line break is detected. * @return The list with the sequences. */ private List supplementalBreakOfSequences(List<KnuthSequence> inlineElements) { List<KnuthSequence> result = new ArrayList<>(); for (KnuthSequence sequence : inlineElements) { // The 'line' that may need to be split in multiple lines. if (sequence.isInlineSequence()) { while(sequence.size() > 0) { int idx = findNextLineBreakIndex(0, sequence); if (idx != -1 && idx != sequence.size() - 1) { result.add(new InlineKnuthSequence(sequence.subList(0, idx + 1))); sequence = new InlineKnuthSequence(sequence.subList(idx + 1, sequence.size())); } else { result.add(sequence); break; } } } else { result.add(sequence); } } return result; } private int findNextLineBreakIndex(int start, KnuthSequence sequence) { int idx = -1; boolean previousIsBox = false; for (int i = 0; i < sequence.size() - 1; i++) { ListElement current = (ListElement) sequence.get(i); if (previousIsBox && current.isForcedBreak()) { idx = i; break; } previousIsBox = current.isBox() && !((KnuthElement) current).isAuxiliary() && ((KnuthElement) current).getWidth() != 0; } return idx; } {code} Invoke the first one in the org.apache.fop.layoutmgr.inline.LineLayoutManager.collectInlineKnuthElements(LayoutContext) method after the inlineElements checking: {code:java} InlineLevelLayoutManager curLM; while ((curLM = (InlineLevelLayoutManager) getChildLM()) != null) { List 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; } // PATCH START inlineElements = supplementalBreakOfSequences(inlineElements); // PATCH END {code} > Excessive wrap when having linefeed-treatment="preserve" and inlines > -------------------------------------------------------------------- > > Key: FOP-2809 > URL: https://issues.apache.org/jira/browse/FOP-2809 > Project: FOP > Issue Type: Bug > Components: layout/line > Affects Versions: 2.3 > Reporter: Dan Caprioara > Priority: Major > > The text should be presented on two lines (they are separated by line breaks > - not by wrapping - is plenty of space in the page): > {quote} > line1 line1 line1 line1 LINE1 > line2 > {quote} > Instead it is on three lines. > {quote} > line1 line1 line1 line1 > LINE1 > line2 > {quote} > The snippet: > {code:xml} > <?xml version="1.0" encoding="UTF-8"?> > <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" > xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" xml:lang="en-us"> > <fo:layout-master-set> > <fo:simple-page-master master-name="css2fo-default" page-width="8.5in" > page-height="11in"> > <fo:region-body margin="1in"/> > </fo:simple-page-master> > </fo:layout-master-set> > <fo:page-sequence master-reference="css2fo-default" > force-page-count="no-force" > id="last-page-sequence" line-height-shift-adjustment="disregard-shifts"> > <fo:flow flow-name="xsl-region-body"> > <fo:block-container> > <fo:block linefeed-treatment="preserve" > wrap-option="wrap"><fo:inline>line1 line1 <fo:inline>line1 line1 > LINE1</fo:inline> > <fo:inline>line2</fo:inline></fo:inline></fo:block> > </fo:block-container> > </fo:flow> > </fo:page-sequence> > </fo:root> > {code} > If you add more words to the example, you will see that it always add a break > before the second-to-last word. > If you remove the inline: {{<fo:inline>line2</fo:inline>}} and leave just the > {{line2}} text, this corrects the problem. The same if you remove the tags > of any inline. -- This message was sent by Atlassian Jira (v8.3.2#803003)