]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-3192: Redo layout for multipage columns
authorSimon Steiner <ssteiner@apache.org>
Tue, 16 Jul 2024 07:34:38 +0000 (08:34 +0100)
committerSimon Steiner <ssteiner@apache.org>
Tue, 16 Jul 2024 07:34:38 +0000 (08:34 +0100)
14 files changed:
fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java
fop-core/src/main/java/org/apache/fop/apps/FopConfParser.java
fop-core/src/main/java/org/apache/fop/apps/FopFactory.java
fop-core/src/main/java/org/apache/fop/apps/FopFactoryBuilder.java
fop-core/src/main/java/org/apache/fop/apps/FopFactoryConfig.java
fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractBreaker.java
fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
fop-core/src/main/java/org/apache/fop/layoutmgr/PageBreaker.java
fop-core/src/test/java/org/apache/fop/apps/MutableConfig.java
fop-core/src/test/java/org/apache/fop/intermediate/TestAssistant.java
fop/test/layoutengine/standard-testcases/page-position_only_5.xml
fop/test/layoutengine/standard-testcases/page-position_only_5_legacy.xml [new file with mode: 0644]
fop/test/layoutengine/standard-testcases/page-position_only_6.xml [new file with mode: 0644]
fop/test/layoutengine/standard-testcases/page-position_only_7.xml [new file with mode: 0644]

index 443b020287830e8045ad94bda14d6db2c77394b2..12707b30bfd3b78bf48c1642865c150d9f064d6b 100644 (file)
@@ -847,4 +847,8 @@ public class FOUserAgent {
     public boolean isSkipPagePositionOnlyAllowed() {
         return factory.isSkipPagePositionOnlyAllowed();
     }
+
+    public boolean isLegacySkipPagePositionOnly() {
+        return factory.isLegacySkipPagePositionOnly();
+    }
 }
index 3bece200257c78cbef3e0954dba664c72b2e2e0e..f36593ed575a7df5343a51d5d289b42ac4a54eea 100644 (file)
@@ -59,6 +59,7 @@ public class FopConfParser {
     private static final String TABLE_BORDER_OVERPAINT = "table-border-overpaint";
     private static final String SIMPLE_LINE_BREAKING = "simple-line-breaking";
     private static final String SKIP_PAGE_POSITION_ONLY_ALLOWED = "skip-page-position-only-allowed";
+    private static final String LEGACY_SKIP_PAGE_POSITION_ONLY = "legacy-skip-page-position-only";
 
     private final Log log = LogFactory.getLog(FopConfParser.class);
 
@@ -299,6 +300,14 @@ public class FopConfParser {
                 LogUtil.handleException(log, e, false);
             }
         }
+        if (cfg.getChild(LEGACY_SKIP_PAGE_POSITION_ONLY, false) != null) {
+            try {
+                fopFactoryBuilder.setLegacySkipPagePositionOnly(
+                        cfg.getChild(LEGACY_SKIP_PAGE_POSITION_ONLY).getValueAsBoolean());
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(log, e, false);
+            }
+        }
 
         // configure font manager
         new FontManagerConfigurator(cfg, baseURI, fopFactoryBuilder.getBaseURI(), resourceResolver)
index 3b90614b42ad0bd934cef00b48a000dbc5cf933f..7696c399746132e18c9a7416c16070ffc39f6c13 100644 (file)
@@ -244,6 +244,10 @@ public final class FopFactory implements ImageContext {
         return config.isSkipPagePositionOnlyAllowed();
     }
 
+    boolean isLegacySkipPagePositionOnly() {
+        return config.isLegacySkipPagePositionOnly();
+    }
+
     /**
      * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
      * instance. Use this factory method if your output type requires an output stream.
index afbcb227e1d78a679a85c2cec81e5051ba157d2b..aa90bd544ce8652153311f41ccf0d97d817fee68 100644 (file)
@@ -355,6 +355,11 @@ public final class FopFactoryBuilder {
         return this;
     }
 
+    public FopFactoryBuilder setLegacySkipPagePositionOnly(boolean b) {
+        fopFactoryConfigBuilder.setLegacySkipPagePositionOnly(b);
+        return this;
+    }
+
     public static class FopFactoryConfigImpl implements FopFactoryConfig {
 
         private final EnvironmentProfile enviro;
@@ -401,6 +406,8 @@ public final class FopFactoryBuilder {
 
         private boolean skipPagePositionOnlyAllowed = true;
 
+        private boolean legacySkipPagePositionOnly;
+
         private static final class ImageContextImpl implements ImageContext {
 
             private final FopFactoryConfig config;
@@ -529,6 +536,10 @@ public final class FopFactoryBuilder {
             return skipPagePositionOnlyAllowed;
         }
 
+        public boolean isLegacySkipPagePositionOnly() {
+            return legacySkipPagePositionOnly;
+        }
+
         public Map<String, String> getHyphenationPatternNames() {
             return hyphPatNames;
         }
@@ -580,6 +591,8 @@ public final class FopFactoryBuilder {
         void setSimpleLineBreaking(boolean b);
 
         void setSkipPagePositionOnlyAllowed(boolean b);
+
+        void setLegacySkipPagePositionOnly(boolean b);
     }
 
     private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -675,6 +688,10 @@ public final class FopFactoryBuilder {
         public void setSkipPagePositionOnlyAllowed(boolean b) {
             throwIllegalStateException();
         }
+
+        public void setLegacySkipPagePositionOnly(boolean b) {
+            throwIllegalStateException();
+        }
     }
 
     private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -771,6 +788,10 @@ public final class FopFactoryBuilder {
         public void setSkipPagePositionOnlyAllowed(boolean b) {
             config.skipPagePositionOnlyAllowed = b;
         }
+
+        public void setLegacySkipPagePositionOnly(boolean b) {
+            config.legacySkipPagePositionOnly = b;
+        }
     }
 
 }
index 55cf7143e67c5d93ba643c2c832717f65a0ebd05..a74b0437ceda06c79e8b94608cdbed6bb8f48f81 100644 (file)
@@ -169,6 +169,8 @@ public interface FopFactoryConfig {
 
     boolean isSkipPagePositionOnlyAllowed();
 
+    boolean isLegacySkipPagePositionOnly();
+
     /** @return the hyphenation pattern names */
     Map<String, String> getHyphenationPatternNames();
 
index e86d9cf50ddf24ffc27ba7ba24bc82eb75ad2d75..9a519276ec9a5b0364f382c3449389efdc2ed2bb 100644 (file)
@@ -382,81 +382,86 @@ public abstract class AbstractBreaker {
         while (hasMoreContent()) {
             blockLists.clear();
 
-            //*** Phase 1: Get Knuth elements ***
-            nextSequenceStartsOn = getNextBlockList(childLC, nextSequenceStartsOn);
-            empty = empty && blockLists.size() == 0;
-
-            //*** Phases 2 and 3 ***
-            log.debug("PLM> blockLists.size() = " + blockLists.size());
-            for (blockListIndex = 0; blockListIndex < blockLists.size(); blockListIndex++) {
-                blockList = blockLists.get(blockListIndex);
-
-                //debug code start
-                if (log.isDebugEnabled()) {
-                    log.debug("  blockListIndex = " + blockListIndex);
-                    log.debug("  sequence starts on " + getBreakClassName(blockList.startOn));
-                }
-                observeElementList(blockList);
-                //debug code end
-
-                //*** Phase 2: Alignment and breaking ***
-                log.debug("PLM> start of algorithm (" + this.getClass().getName()
-                        + "), flow BPD =" + flowBPD);
-                PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(),
-                         getPageProvider(), createLayoutListener(),
-                         alignment, alignmentLast, footnoteSeparatorLength,
-                         isPartOverflowRecoveryActivated(), autoHeight, isSinglePartFavored());
-
-                alg.setConstantLineWidth(flowBPD);
-                int optimalPageCount = alg.findBreakingPoints(blockList, 1, true,
-                        BreakingAlgorithm.ALL_BREAKS);
-                boolean ipdChangesOnNextPage = (alg.getIPDdifference() != 0);
-                boolean onLastPageAndIPDChanges = false;
-                if (!ipdChangesOnNextPage) {
-                    onLastPageAndIPDChanges = (lastPageHasIPDChange(optimalPageCount) && !thereIsANonRestartableLM(alg)
-                            && (shouldRedoLayout() || (wasLayoutRedone() && optimalPageCount > 1)));
-                }
-                if (shouldRedoLayoutWithoutPagePositionOnly(ipdChangesOnNextPage, optimalPageCount)) {
-                    return false;
-                }
-                if (alg.handlingFloat()) {
-                    nextSequenceStartsOn = handleFloatLayout(alg, optimalPageCount, blockList, childLC);
-                } else if (ipdChangesOnNextPage || onLastPageAndIPDChanges) {
-                    boolean visitedBefore = false;
-                    if (onLastPageAndIPDChanges) {
-                        visitedBefore = wasLayoutRedone();
-                        prepareToRedoLayout(alg, optimalPageCount, blockList, blockList);
+            try {
+                //*** Phase 1: Get Knuth elements ***
+                nextSequenceStartsOn = getNextBlockList(childLC, nextSequenceStartsOn);
+                empty = empty && blockLists.size() == 0;
+
+                //*** Phases 2 and 3 ***
+                log.debug("PLM> blockLists.size() = " + blockLists.size());
+                for (blockListIndex = 0; blockListIndex < blockLists.size(); blockListIndex++) {
+                    blockList = blockLists.get(blockListIndex);
+
+                    //debug code start
+                    if (log.isDebugEnabled()) {
+                        log.debug("  blockListIndex = " + blockListIndex);
+                        log.debug("  sequence starts on " + getBreakClassName(blockList.startOn));
                     }
-
-                    firstElementsForRestart = null;
-                    RestartAtLM restartAtLMClass = new RestartAtLM();
-                    LayoutManager restartAtLM = restartAtLMClass.getRestartAtLM(this, alg, ipdChangesOnNextPage,
-                            onLastPageAndIPDChanges, visitedBefore, blockList, 1);
-                    if (restartAtLMClass.invalidPosition) {
+                    observeElementList(blockList);
+                    //debug code end
+
+                    //*** Phase 2: Alignment and breaking ***
+                    log.debug("PLM> start of algorithm (" + this.getClass().getName()
+                            + "), flow BPD =" + flowBPD);
+                    PageBreakingAlgorithm alg = new PageBreakingAlgorithm(getTopLevelLM(),
+                             getPageProvider(), createLayoutListener(),
+                             alignment, alignmentLast, footnoteSeparatorLength,
+                             isPartOverflowRecoveryActivated(), autoHeight, isSinglePartFavored());
+
+                    alg.setConstantLineWidth(flowBPD);
+                    int optimalPageCount = alg.findBreakingPoints(blockList, 1, true,
+                            BreakingAlgorithm.ALL_BREAKS);
+                    boolean ipdChangesOnNextPage = (alg.getIPDdifference() != 0);
+                    boolean onLastPageAndIPDChanges = false;
+                    if (!ipdChangesOnNextPage) {
+                        onLastPageAndIPDChanges = (lastPageHasIPDChange(optimalPageCount)
+                                && !thereIsANonRestartableLM(alg)
+                                && (shouldRedoLayout() || (wasLayoutRedone() && optimalPageCount > 1)));
+                    }
+                    if (shouldRedoLayoutWithoutPagePositionOnly(ipdChangesOnNextPage, optimalPageCount, alg)) {
                         return false;
                     }
-                    if (restartAtLM == null || restartAtLM.getChildLMs().isEmpty()) {
+                    if (alg.handlingFloat()) {
+                        nextSequenceStartsOn = handleFloatLayout(alg, optimalPageCount, blockList, childLC);
+                    } else if (ipdChangesOnNextPage || onLastPageAndIPDChanges) {
+                        boolean visitedBefore = false;
+                        if (onLastPageAndIPDChanges) {
+                            visitedBefore = wasLayoutRedone();
+                            prepareToRedoLayout(alg, optimalPageCount, blockList, blockList);
+                        }
+
                         firstElementsForRestart = null;
-                        LayoutManager restartAtLM2 = new RestartAtLM().getRestartAtLM(this, alg, ipdChangesOnNextPage,
-                                onLastPageAndIPDChanges, visitedBefore, blockList, 0);
-                        if (restartAtLM2 != null) {
-                            restartAtLM = restartAtLM2;
+                        RestartAtLM restartAtLMClass = new RestartAtLM();
+                        LayoutManager restartAtLM = restartAtLMClass.getRestartAtLM(this, alg, ipdChangesOnNextPage,
+                                onLastPageAndIPDChanges, visitedBefore, blockList, 1);
+                        if (restartAtLMClass.invalidPosition) {
+                            return false;
                         }
-                    }
-                    if (ipdChangesOnNextPage) {
-                        addAreas(alg, optimalPageCount, blockList, blockList);
-                    }
-                    blockLists.clear();
-                    blockListIndex = -1;
-                    nextSequenceStartsOn = getNextBlockList(childLC, Constants.EN_COLUMN, positionAtBreak,
-                            restartAtLM, firstElementsForRestart);
-                } else {
-                    log.debug("PLM> optimalPageCount= " + optimalPageCount
-                            + " pageBreaks.size()= " + alg.getPageBreaks().size());
+                        if (restartAtLM == null || restartAtLM.getChildLMs().isEmpty()) {
+                            firstElementsForRestart = null;
+                            LayoutManager restartAtLM2 = new RestartAtLM().getRestartAtLM(this, alg,
+                                    ipdChangesOnNextPage, onLastPageAndIPDChanges, visitedBefore, blockList, 0);
+                            if (restartAtLM2 != null) {
+                                restartAtLM = restartAtLM2;
+                            }
+                        }
+                        if (ipdChangesOnNextPage) {
+                            addAreas(alg, optimalPageCount, blockList, blockList);
+                        }
+                        blockLists.clear();
+                        blockListIndex = -1;
+                        nextSequenceStartsOn = getNextBlockList(childLC, Constants.EN_COLUMN, positionAtBreak,
+                                restartAtLM, firstElementsForRestart);
+                    } else {
+                        log.debug("PLM> optimalPageCount= " + optimalPageCount
+                                + " pageBreaks.size()= " + alg.getPageBreaks().size());
 
-                    //*** Phase 3: Add areas ***
-                    doPhase3(alg, optimalPageCount, blockList, blockList);
+                        //*** Phase 3: Add areas ***
+                        doPhase3(alg, optimalPageCount, blockList, blockList);
+                    }
                 }
+            } catch (PagePositionOnlyException e) {
+                return false;
             }
         }
 
@@ -465,11 +470,26 @@ public abstract class AbstractBreaker {
         return true;
     }
 
-    private boolean shouldRedoLayoutWithoutPagePositionOnly(boolean ipdChangesOnNextPage, int optimalPageCount) {
+    static class PagePositionOnlyException extends RuntimeException {
+    }
+
+    private boolean shouldRedoLayoutWithoutPagePositionOnly(boolean ipdChangesOnNextPage, int optimalPageCount,
+                                                            PageBreakingAlgorithm alg) {
         if ((ipdChangesOnNextPage || hasMoreContent() || optimalPageCount > 1)
                 && pslm != null && pslm.getCurrentPage().isPagePositionOnly) {
+            if (getPageProvider().foUserAgent.isLegacySkipPagePositionOnly()) {
+                return true;
+            }
             RegionBody rb = (RegionBody)pslm.getCurrentPage().getSimplePageMaster().getRegion(Constants.FO_REGION_BODY);
-            return rb.getColumnCount() == 1;
+            if (rb.getColumnCount() == 1) {
+                return true;
+            }
+            int restartPoint = getPageProvider().getStartingPartIndexForLastPage(optimalPageCount);
+            if (restartPoint > 0) {
+                PageBreakPosition pbp = (PageBreakPosition) alg.getPageBreaks().get(restartPoint - 1);
+                int newStartPos = alg.par.getFirstBoxIndex(pbp.getLeafPos() + 1);
+                return newStartPos > 0;
+            }
         }
         return false;
     }
index ff693ed67bdfd465ddfb90b2d6bc824394b6674c..616de6850a001d4ea87b952c298b91f1bfccfbdf 100644 (file)
@@ -67,7 +67,7 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager im
     private int lastGeneratedPosition = -1;
     private int smallestPosNumberChecked = Integer.MAX_VALUE;
 
-    private boolean preserveChildrenAtEndOfLayout;
+    private boolean preserveChildrenAtEndOfLayout = true;
 
     /**
      * Abstract layout manager.
index 1e9a1e87bfbc626ff3babe89b244a72ea2277799..d95bd3c48490ca32843fd98c871646fcd6ffde69 100644 (file)
@@ -632,6 +632,10 @@ public class PageBreaker extends AbstractBreaker {
                         log.trace("Moving to next flow");
                         pv.getCurrentSpan().moveToNextFlow();
                     } else {
+                        if (pslm.getCurrentPage().isPagePositionOnly
+                                && !pslm.fobj.getUserAgent().isLegacySkipPagePositionOnly()) {
+                            throw new PagePositionOnlyException();
+                        }
                         log.trace("Making new page");
                         pslm.makeNewPage(false, emptyContent);
                     }
index 27ff94f7c79f8f4064faf44afd037500bdc6e672..17348a2e658e645e6612e5c37b2c41081642f33e 100644 (file)
@@ -145,6 +145,10 @@ public final class MutableConfig implements FopFactoryConfig {
         return delegate.isSkipPagePositionOnlyAllowed();
     }
 
+    public boolean isLegacySkipPagePositionOnly() {
+        return delegate.isLegacySkipPagePositionOnly();
+    }
+
     public Map<String, String> getHyphenationPatternNames() {
         return delegate.getHyphenationPatternNames();
     }
index daf4b50dc1bf4020b4e2b1afaa281fa12b9bbde3..8b5aad6c226f35261c84f3d1fcba27d723699ab5 100644 (file)
@@ -126,6 +126,7 @@ public class TestAssistant {
         builder.setTableBorderOverpaint(isTableBorderOverpaint(testDoc));
         builder.setSimpleLineBreaking(isSimpleLineBreaking(testDoc));
         builder.setSkipPagePositionOnlyAllowed(isSkipPagePositionOnlyAllowed(testDoc));
+        builder.setLegacySkipPagePositionOnly(isLegacySkipPagePositionOnly(testDoc));
         return builder.build();
     }
 
@@ -179,6 +180,15 @@ public class TestAssistant {
         }
     }
 
+    private boolean isLegacySkipPagePositionOnly(Document testDoc) {
+        try {
+            String s = eval(testDoc, "/testcase/cfg/legacy-skip-page-position-only");
+            return "true".equalsIgnoreCase(s);
+        } catch (XPathExpressionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     /**
      * Loads a test case into a DOM document.
      * @param testFile the test file
index 6319485340071bca3dda93da6e1dd41ca966ecf5..24ccfe8c2094bb986cf200394d7f47f2c08ed08f 100644 (file)
@@ -80,6 +80,7 @@
     </fo:root>
   </fo>
   <checks>
+    <eval expected="236" xpath="count(//word)"/>
     <eval expected="1" xpath="count(//page)"/>
     <eval expected="PageOnly" xpath="//pageViewport/@simple-page-master-name"/>
   </checks>
diff --git a/fop/test/layoutengine/standard-testcases/page-position_only_5_legacy.xml b/fop/test/layoutengine/standard-testcases/page-position_only_5_legacy.xml
new file mode 100644 (file)
index 0000000..c0c72e2
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks for the use of an 'only' conditional-page-master-reference (XSL 1.1)
+    </p>
+  </info>
+  <cfg>
+    <legacy-skip-page-position-only>true</legacy-skip-page-position-only>
+  </cfg>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="PageOnly" page-width="8.5in" page-height="11in" margin-bottom="0.5cm" margin-right="1cm" margin-top="1cm" margin-left="1cm">
+          <fo:region-body margin-bottom="2cm" margin-right="0cm" margin-top="0cm" margin-left="0cm" background-color="red" column-count="2"/>
+          <fo:region-after extent="1cm" region-name="Footer1"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master margin-bottom="0.5cm" master-name="PageFirst" page-width="8.5in" page-height="11in" margin-right="1cm" margin-top="1cm" margin-left="1cm">
+          <fo:region-body margin-bottom="2cm" margin-right="0cm" margin-top="0cm" margin-left="0cm" background-color="yellow" column-count="2"/>
+          <fo:region-after extent="1cm" region-name="Footer2"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="PageLast" page-width="8.5in" page-height="11in" margin-bottom="0.3cm" margin-right="1cm" margin-top="1cm" margin-left="1cm">
+          <fo:region-body margin-bottom="2cm" column-count="2" background-color="green" margin-right="0cm" margin-top="0cm" margin-left="0cm"/>
+          <fo:region-after extent="1cm" region-name="Footer3"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="PageRestEven" page-width="8.5in" page-height="11in" margin-bottom="0.3cm" margin-right="1cm" margin-top="1cm" margin-left="1cm">
+          <fo:region-body margin-bottom="2cm" column-count="2" background-color="aqua" margin-right="0cm" margin-top="0cm" margin-left="0cm"/>
+          <fo:region-after extent="1cm" region-name="Footer4"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="PageRestOdd" page-width="8.5in" page-height="11in" margin-bottom="0.3cm" margin-right="1cm" margin-top="1cm" margin-left="1cm">
+          <fo:region-body margin-bottom="2cm" column-count="2" background-color="fuchsia" margin-right="0cm" margin-top="0cm" margin-left="0cm"/>
+          <fo:region-after extent="1cm" region-name="Footer5"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="LetterPages">
+          <fo:repeatable-page-master-alternatives>
+            <fo:conditional-page-master-reference page-position="only" master-reference="PageOnly"/>
+            <fo:conditional-page-master-reference page-position="first" master-reference="PageFirst"/>
+            <fo:conditional-page-master-reference odd-or-even="even" page-position="rest" master-reference="PageRestEven"/>
+            <fo:conditional-page-master-reference odd-or-even="odd" page-position="rest" master-reference="PageRestOdd"/>
+            <fo:conditional-page-master-reference page-position="last" master-reference="PageLast"/>
+          </fo:repeatable-page-master-alternatives>
+        </fo:page-sequence-master>
+      </fo:layout-master-set>
+      <fo:page-sequence format="1" id="th_default_sequence1" initial-page-number="1" force-page-count="auto" master-reference="LetterPages">
+        <fo:static-content flow-name="Footer1">
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt" span="all">Footer 1</fo:block>
+        </fo:static-content>
+        <fo:static-content flow-name="Footer2">
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt" span="all">Footer 2</fo:block>
+        </fo:static-content>
+        <fo:static-content flow-name="Footer3">
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt" span="all">Footer 3</fo:block>
+        </fo:static-content>
+        <fo:static-content flow-name="Footer4">
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt" span="all">Footer 4</fo:block>
+        </fo:static-content>
+        <fo:static-content flow-name="Footer5">
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt" span="all">Footer 5</fo:block>
+        </fo:static-content>
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt" span="all">Page 1 Page 1 Page 1 Page 1 Page 1 Page 1 Page 1 Page 1 Page 1 Page 1</fo:block>
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt">bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw bgbg gresgfe rwfwr rfrw fwrfrw </fo:block>
+          <fo:block line-height="16pt" font-size="10pt" space-before="12pt" span="all">end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="236" xpath="count(//word)"/>
+    <eval expected="1" xpath="count(//page)"/>
+    <eval expected="PageFirst" xpath="//pageViewport/@simple-page-master-name"/>
+  </checks>
+</testcase>
diff --git a/fop/test/layoutengine/standard-testcases/page-position_only_6.xml b/fop/test/layoutengine/standard-testcases/page-position_only_6.xml
new file mode 100644 (file)
index 0000000..51cb97e
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks the page-position first is used as there is not enough space on page-position only.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="PageOnly" page-width="8.5in" page-height="11in" margin-bottom="0.25in" margin-right="0.5in" margin-top="0.35in" margin-left="0.5in">
+          <fo:region-body background-color="red" margin-top="0.85in" margin-bottom="2.1in" column-gap="0.3in" column-count="2" region-name="PageBody"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master margin-right="0.5in" margin-left="0.5in" margin-top="0.35in" margin-bottom="0.25in" master-name="PageFirst" page-width="8.5in" page-height="11in">
+          <fo:region-body background-color="blue" margin-top="0.85in" column-count="2" column-gap="0.3in" margin-bottom="1in" region-name="PageBody"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="PageRest" margin-right="0.5in" margin-left="0.5in" margin-top="0.35in" margin-bottom="0.25in" page-width="8.5in" page-height="11in">
+          <fo:region-body margin-bottom="1in" margin-top="0.5in" column-gap="0.3in" column-count="2" region-name="PageBody"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="LetterPages">
+          <fo:repeatable-page-master-alternatives>
+            <fo:conditional-page-master-reference page-position="only" master-reference="PageOnly"/>
+            <fo:conditional-page-master-reference page-position="first" master-reference="PageFirst"/>
+            <fo:conditional-page-master-reference page-position="rest" master-reference="PageRest"/>
+            <fo:conditional-page-master-reference page-position="last" master-reference="PageRest"/>
+          </fo:repeatable-page-master-alternatives>
+        </fo:page-sequence-master>
+      </fo:layout-master-set>
+      <fo:page-sequence format="1" id="th_default_sequence1" initial-page-number="auto" force-page-count="auto" master-reference="LetterPages">
+        <fo:flow flow-name="PageBody">
+          <fo:block-container span="all" id="1">
+            <fo:block>test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </fo:block>
+          </fo:block-container>
+          <fo:block-container id="2">
+            <fo:block>
+              <fo:block font-size="30pt">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </fo:block>
+            </fo:block>
+          </fo:block-container>
+          <fo:block-container span="all" id="3">
+            <fo:block>
+              <fo:block>
+                <fo:leader/>
+              </fo:block>
+            </fo:block>
+          </fo:block-container>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="216" xpath="count(//word)"/>
+    <eval expected="1" xpath="count(//page)"/>
+    <eval expected="PageFirst" xpath="//pageViewport/@simple-page-master-name"/>
+  </checks>
+</testcase>
diff --git a/fop/test/layoutengine/standard-testcases/page-position_only_7.xml b/fop/test/layoutengine/standard-testcases/page-position_only_7.xml
new file mode 100644 (file)
index 0000000..48bc502
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks the page-position only is not used as there is more than 1 page
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" font-family="Helvetica">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="PageFrontSingle" page-width="8.5in" page-height="11in" margin-bottom="0.32in" margin-right="1in" margin-top="0.2in" margin-left="0.9in">
+          <fo:region-body margin-bottom="1.35in" margin-right="0in" margin-top="0.5in" margin-left="0in" column-gap=".5in" column-count="2" region-name="letterPageBody" background-color="yellow"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="PageFront" page-width="8.5in" page-height="11in" margin-bottom="0.32in" margin-right="1in" margin-top="0.2in" margin-left="0.9in">
+          <fo:region-body margin-bottom="0.7in" margin-right="0in" margin-top="0.5in" margin-left="0in" column-gap=".5in" column-count="2" region-name="letterPageBody" background-color="orange"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="PageRest" page-width="8.5in" page-height="11in" margin-bottom="0.32in" margin-right="1in" margin-top="0.7in" margin-left="0.9in">
+          <fo:region-body margin-bottom="0.7in" margin-right="0in" margin-top="0in" margin-left="0in" column-gap=".5in" column-count="2" region-name="letterPageBody" background-color="red"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="PageLast" page-width="8.5in" page-height="11in" margin-bottom="0.32in" margin-right="1in" margin-top="0.7in" margin-left="0.9in">
+          <fo:region-body margin-bottom="1.35in" margin-right="0in" margin-top="0in" margin-left="0in" region-name="LetterPageBody" background-color="pink"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="LetterPages">
+          <fo:repeatable-page-master-alternatives>
+            <fo:conditional-page-master-reference page-position="only" master-reference="PageFrontSingle"/>
+            <fo:conditional-page-master-reference page-position="first" master-reference="PageFront"/>
+            <fo:conditional-page-master-reference page-position="rest" master-reference="PageRest"/>
+            <fo:conditional-page-master-reference page-position="last" master-reference="PageLast"/>
+          </fo:repeatable-page-master-alternatives>
+        </fo:page-sequence-master>
+      </fo:layout-master-set>
+      <fo:page-sequence format="1" id="th_default_sequence1" initial-page-number="auto" force-page-count="auto" master-reference="LetterPages">
+        <fo:flow flow-name="letterPageBody">
+          <fo:block font-size="60pt">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="124" xpath="count(//word)"/>
+    <eval expected="4" xpath="count(//page)"/>
+    <eval expected="PageFront" xpath="//pageViewport/@simple-page-master-name"/>
+  </checks>
+</testcase>