You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-dev@xmlgraphics.apache.org by "Dan Caprioara (Jira)" <ji...@apache.org> on 2019/09/06 13:25:00 UTC
[jira] [Commented] (FOP-2809) Excessive wrap when having
linefeed-treatment="preserve" and inlines
[ 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)