[
https://issues.apache.org/jira/browse/FOP-3348?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Joao Goncalves resolved FOP-3348.
---------------------------------
Fix Version/s: main
Resolution: Fixed
https://github.com/joao12021996/xmlgraphics-fop/pull/37/changes/4f7c582321fb698033b54fefc549ebb7d489718a
> A block nested in an inline loses the lines after it, and FOP throws a
> NullPointerException in TraitSetter.setVisibility, when line breaking runs
> again (after a float, or on a page of a different IPD)
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: FOP-3348
> URL: https://issues.apache.org/jira/browse/FOP-3348
> Project: FOP
> Issue Type: Bug
> Components: layout/line
> Affects Versions: 2.11, main
> Reporter: Jason Harrop
> Priority: Major
> Fix For: main
>
>
> LineLayoutManager keeps a paragraph's Knuth sequences in knuthParagraphs. A
> block nested in an inline gives it a block-level sequence between two inline
> ones. postProcessLineBreaks passes that block-level sequence's elements
> upward as the same objects it stores, wrapping each in place:
> {code:java}
> tempElement.setPosition(notifyPos(new NonLeafPosition(this,
> tempElement.getPosition())));
> {code}
> The enclosing block and flow managers wrap the same objects in place again
> (BlockStackingLayoutManager.wrapPositionElements).
> Line breaking runs a second time over the stored paragraphs in two cases: the
> content after a float (PageBreaker.handleFloatLayout restarts after it), and
> the restart after a change of IPD. The elements still carry the first pass's
> wrapping, so they are wrapped twice. With a float, the nested block's chain
> came out LineLM > FlowLM > BlockLM > LineLM > InlineLM > BlockLM, where it
> should be LineLM > InlineLM > BlockLM.
> LineLayoutManager.addBlockArea unwraps one level, reaches the
> FlowLayoutManager, and so re-enters the enclosing block's addAreas. That
> inner call flushes the block's area and sets curBlockArea to null. Back in
> the outer call, the line after the nested block reaches addChildArea, which
> drops it silently while the area is null. Then
> TraitSetter.setVisibility(curBlockArea, ...) throws the NullPointerException.
> A null check there would stop the exception and lose the text.
> h3. To reproduce
> 1. A float, then a paragraph with a block inside an inline:
> {code:xml}
> <fo:block><fo:float float="start"><fo:block-container width="100pt"
> height="60pt">
> <fo:block>Float</fo:block></fo:block-container></fo:float>Some text beside
> it.</fo:block>
> <fo:block>Before <fo:inline>the run<fo:block
> linefeed-treatment="preserve">
</fo:block>after
> the break and on.</fo:inline></fo:block>
> {code}
> 2. Without a float: the same paragraph breaking onto a page whose region-body
> is narrower (a page-sequence-master whose later pages have a larger
> margin-left).
> Both throw on 2.11 and on main. Without the float, or with pages of equal
> width, the same FO lays out completely.
> h3. Fix
> Before wrapping such an element, walk its chain of NonLeafPositions. If one
> of them belongs to this manager, an earlier pass left it there, so start
> again from the position inside it. On a first pass none does, so nothing
> changes. Only NonLeafPositions are walked: the wrapping is made of them, and
> a TableContentPosition returns itself from getPosition().
> Tests: layout tests inline_block_nested_float_relayout.xml (the float form)
> and inline_block_nested_ipd_relayout.xml (the page-width form). Both fail
> with the NullPointerException before the fix. With it, the layout engine
> suite passes on main (743 standard test cases; the 34 in
> disabled-testcases.xml do not run).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)