]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fix FOP-3098. Submitted by Dave Roxburgh
authorChris Bowditch <cbowditch@apache.org>
Thu, 2 Mar 2023 15:27:00 +0000 (15:27 +0000)
committerChris Bowditch <cbowditch@apache.org>
Thu, 2 Mar 2023 15:27:00 +0000 (15:27 +0000)
fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
fop/test/layoutengine/standard-testcases/float_9.xml [new file with mode: 0644]

index ffc4e7c885992891d06f1c025f6593f1dac7d2bf..a15e58ad469ea87b5248f476470b0bb7dcfd48c0 100644 (file)
@@ -436,6 +436,15 @@ public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManage
             addedBoxHeight += boxHeight;
             ListItemPosition stepPosition = new ListItemPosition(this, start[0], end[0], start[1], end[1]);
             stepPosition.setOriginalLabelPosition(originalLabelPosition);
+            if (originalBodyPosition != null && originalBodyPosition.getLM() instanceof ListItemContentLayoutManager) {
+                // Happens when ListItem has multiple blocks and a block (that's not the last block) ends at the same
+                // page height as a IPD change (e.g. FOP-3098). originalBodyPosition (reset) position needs to be a
+                // Block so that BlockStackingLayoutManager can stack it. Lookahead to find next Block.
+                Position block = extractBlock(elementLists[1], end[1] + 1);
+                if (block != null) {
+                    originalBodyPosition = block;
+                }
+            }
             stepPosition.setOriginalBodyPosition(originalBodyPosition);
 
             if (floats.isEmpty()) {
@@ -467,6 +476,37 @@ public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManage
         return returnList;
     }
 
+    /**
+     * Extracts a block Position from a ListElement at a given index in a list of ListItem body elements.
+     * @param bodyElements The ListItem body elements.
+     * @param index        The index of the ListElement containing the block.
+     * @return             The required block Position as a LeafPosition or null on failure.
+     */
+    private Position extractBlock(List<ListElement> bodyElements, int index) {
+        ListElement listElement;
+        Position position = null;
+        Position retval = null;
+        do {
+            if (bodyElements == null || index >= bodyElements.size()) {
+                break;
+            }
+            listElement = bodyElements.get(index);
+            if (listElement != null
+                    && listElement.getLayoutManager() instanceof ListItemContentLayoutManager) {
+                position = listElement.getPosition();
+                if (position != null
+                        && position.getLM() instanceof ListItemContentLayoutManager) {
+                    position = position.getPosition();
+                    if (position != null
+                            && position.getLM() instanceof BlockLayoutManager) {
+                        retval = new LeafPosition(position.getPosition().getLM(), 0);
+                    }
+                }
+            }
+        } while (false);
+        return retval;
+    }
+
     private boolean shouldWeAvoidBreak(List returnList, LayoutManager lm) {
         if (isChangingIPD(lm)) {
             if (lm instanceof BlockLayoutManager) {
diff --git a/fop/test/layoutengine/standard-testcases/float_9.xml b/fop/test/layoutengine/standard-testcases/float_9.xml
new file mode 100644 (file)
index 0000000..17bf546
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<testcase>
+  <info>
+    <p>
+      This test checks floats.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
+             font-family="Arial"
+             font-size="10pt">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="A4-portrait"
+                               page-height="297mm"
+                               page-width="210mm"
+                               margin="25mm 15mm 20mm 15mm">
+          <fo:region-body region-name="body" margin="0mm 0mm 0mm 0mm"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="pages">
+          <fo:repeatable-page-master-alternatives>
+            <fo:conditional-page-master-reference master-reference="A4-portrait"/>
+          </fo:repeatable-page-master-alternatives>
+        </fo:page-sequence-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="pages">
+        <fo:flow flow-name="body">
+          <fo:block>
+            <fo:block font-size="13.5pt"
+                      space-before="10mm"
+                      space-before.precedence="20"
+                      space-after="4mm"
+                      font-family="Arial">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam</fo:block>
+            <fo:block space-after="10pt">
+              <fo:float float="right">
+                <fo:block>
+                  <fo:external-graphic width="130pt"
+                                       height="130pt"
+                                       content-width="100pt"
+                                       content-height="100pt"
+                                       src="unknown-token"/>
+                </fo:block>
+              </fo:float>
+              <fo:inline font-size="12pt">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
+                eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et
+                accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem
+                ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing e</fo:inline>
+            </fo:block>
+          </fo:block>
+          <fo:list-block space-before="0mm"
+                         provisional-distance-between-starts="6mm"
+                         provisional-label-separation="1mm">
+            <fo:list-item space-before="0mm">
+              <fo:list-item-label end-indent="label-end()">
+                <fo:block font-size="4pt"> </fo:block>
+              </fo:list-item-label>
+              <fo:list-item-body start-indent="body-start()">
+                <fo:block font-size="12pt">Yes, I would like to use all the options listed below in the sections
+                  Individual Consent, XXXXXXXX-XXXX Ecosystem Consent and Further Individualization and give the
+                  corresponding consent to the use of my dataX Plus another line of text Plus another line of text Plus
+                  another line of</fo:block>
+                <fo:block>
+                  123456789
+                </fo:block>
+              </fo:list-item-body>
+            </fo:list-item>
+          </fo:list-block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <!-- Check float dimensions -->
+    <eval expected="130000" xpath="//pageViewport/page/regionViewport//flow/block[2]/block/lineArea/viewport/@ipda" />
+    <eval expected="130000" xpath="//pageViewport/page/regionViewport//flow/block[2]/block/lineArea/viewport/@bpda" />
+
+    <!-- Check ipd of layout of content of first ListItemBody block, rendered alongside float. This unit test is
+        negated if the last word is wrapped. -->
+    <eval expected="380237" xpath="//pageViewport/page/regionViewport//flow/block[4]/@ipd" />
+    <eval expected="of" xpath="
+        //pageViewport/page/regionViewport//flow/block[4]/block/block[2]/block/lineArea[4]/text/word[last()]/text()" />
+
+    <!-- Check ipd and content of second ListItemBody block, rendered beneath float -->
+    <eval expected="510237" xpath="//pageViewport/page/regionViewport//flow/block[5]/@ipd" />
+    <eval expected="123456789" xpath="
+        //pageViewport/page/regionViewport//flow/block[5]/block/block/block/lineArea/text/word/text()" />
+  </checks>
+</testcase>
+