]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-3090: Allow use of page position only on redo of layout
authorSimon Steiner <ssteiner@apache.org>
Thu, 6 Apr 2023 11:54:38 +0000 (12:54 +0100)
committerSimon Steiner <ssteiner@apache.org>
Thu, 6 Apr 2023 11:54:38 +0000 (12:54 +0100)
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/PageProvider.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_4.xml [new file with mode: 0644]

index 3ab871dfc676a8031ca46786798a34d875f6095e..02b0128cde1149743aaa76b90f800849a9ebaedc 100644 (file)
@@ -839,4 +839,8 @@ public class FOUserAgent {
     public boolean isSimpleLineBreaking() {
         return factory.isSimpleLineBreaking();
     }
+
+    public boolean isSkipPagePositionOnlyAllowed() {
+        return factory.isSkipPagePositionOnlyAllowed();
+    }
 }
index 7e41de6246f5eaedd8b5bbba80351c4e8c0467ff..3bece200257c78cbef3e0954dba664c72b2e2e0e 100644 (file)
@@ -58,6 +58,7 @@ public class FopConfParser {
     private static final String PREFER_RENDERER = "prefer-renderer";
     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 final Log log = LogFactory.getLog(FopConfParser.class);
 
@@ -290,6 +291,15 @@ public class FopConfParser {
             }
         }
 
+        if (cfg.getChild(SKIP_PAGE_POSITION_ONLY_ALLOWED, false) != null) {
+            try {
+                fopFactoryBuilder.setSkipPagePositionOnlyAllowed(
+                        cfg.getChild(SKIP_PAGE_POSITION_ONLY_ALLOWED).getValueAsBoolean());
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(log, e, false);
+            }
+        }
+
         // configure font manager
         new FontManagerConfigurator(cfg, baseURI, fopFactoryBuilder.getBaseURI(), resourceResolver)
                 .configure(fopFactoryBuilder.getFontManager(), strict);
index 8bcbf01fda92830ce74897150419a1eda1814928..0c57d264316cf1357ff77283099d848f0cd9a918 100644 (file)
@@ -223,6 +223,10 @@ public final class FopFactory implements ImageContext {
         return config.isSimpleLineBreaking();
     }
 
+    boolean isSkipPagePositionOnlyAllowed() {
+        return config.isSkipPagePositionOnlyAllowed();
+    }
+
     /**
      * 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 848454e7ff1defde6695a5744d971cb12050ebb3..afbcb227e1d78a679a85c2cec81e5051ba157d2b 100644 (file)
@@ -350,6 +350,11 @@ public final class FopFactoryBuilder {
         return this;
     }
 
+    public FopFactoryBuilder setSkipPagePositionOnlyAllowed(boolean b) {
+        fopFactoryConfigBuilder.setSkipPagePositionOnlyAllowed(b);
+        return this;
+    }
+
     public static class FopFactoryConfigImpl implements FopFactoryConfig {
 
         private final EnvironmentProfile enviro;
@@ -394,6 +399,8 @@ public final class FopFactoryBuilder {
         private boolean tableBorderOverpaint;
         private boolean simpleLineBreaking;
 
+        private boolean skipPagePositionOnlyAllowed = true;
+
         private static final class ImageContextImpl implements ImageContext {
 
             private final FopFactoryConfig config;
@@ -518,6 +525,10 @@ public final class FopFactoryBuilder {
             return simpleLineBreaking;
         }
 
+        public boolean isSkipPagePositionOnlyAllowed() {
+            return skipPagePositionOnlyAllowed;
+        }
+
         public Map<String, String> getHyphenationPatternNames() {
             return hyphPatNames;
         }
@@ -567,6 +578,8 @@ public final class FopFactoryBuilder {
         void setTableBorderOverpaint(boolean b);
 
         void setSimpleLineBreaking(boolean b);
+
+        void setSkipPagePositionOnlyAllowed(boolean b);
     }
 
     private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -658,6 +671,10 @@ public final class FopFactoryBuilder {
         public void setSimpleLineBreaking(boolean b) {
             throwIllegalStateException();
         }
+
+        public void setSkipPagePositionOnlyAllowed(boolean b) {
+            throwIllegalStateException();
+        }
     }
 
     private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
@@ -750,6 +767,10 @@ public final class FopFactoryBuilder {
         public void setSimpleLineBreaking(boolean b) {
             config.simpleLineBreaking = b;
         }
+
+        public void setSkipPagePositionOnlyAllowed(boolean b) {
+            config.skipPagePositionOnlyAllowed = b;
+        }
     }
 
 }
index c9495afb8096d0cc65e069c0c965a65d970ea669..55cf7143e67c5d93ba643c2c832717f65a0ebd05 100644 (file)
@@ -167,6 +167,8 @@ public interface FopFactoryConfig {
 
     boolean isSimpleLineBreaking();
 
+    boolean isSkipPagePositionOnlyAllowed();
+
     /** @return the hyphenation pattern names */
     Map<String, String> getHyphenationPatternNames();
 
index 7926ba756de18dde2550b885f56084d8de821f63..3782806949fa237ef766e34bd052999f63c8db79 100644 (file)
@@ -24,6 +24,7 @@ import java.util.List;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.area.AreaTreeHandler;
 import org.apache.fop.area.BodyRegion;
 import org.apache.fop.area.PageViewport;
@@ -78,6 +79,7 @@ public class PageProvider implements Constants {
     private PageSequence pageSeq;
 
     protected boolean skipPagePositionOnly;
+    protected FOUserAgent foUserAgent;
 
     /**
      * Main constructor.
@@ -88,6 +90,7 @@ public class PageProvider implements Constants {
         this.areaTreeHandler = ath;
         this.pageSeq = ps;
         this.startPageOfPageSequence = ps.getStartingPageNumber();
+        foUserAgent = ath.getUserAgent();
     }
 
     public void initialize() {
@@ -358,11 +361,12 @@ public class PageProvider implements Constants {
     private Page cacheNextPage(int index, boolean isBlank, boolean isLastPage, boolean spanAll) {
         String pageNumberString = pageSeq.makeFormattedPageNumber(index);
         boolean isFirstPage = (startPageOfPageSequence == index);
+        boolean skipPagePositionOnlyCheck = skipPagePositionOnly && foUserAgent.isSkipPagePositionOnlyAllowed();
         SimplePageMaster spm = pageSeq.getNextSimplePageMaster(
-                index, isFirstPage, isLastPage, isBlank, skipPagePositionOnly);
+                index, isFirstPage, isLastPage, isBlank, skipPagePositionOnlyCheck);
         boolean isPagePositionOnly = pageSeq.hasPagePositionOnly() && !skipPagePositionOnly;
         if (isPagePositionOnly) {
-            spm = pageSeq.getNextSimplePageMaster(index, isFirstPage, true, isBlank, skipPagePositionOnly);
+            spm = pageSeq.getNextSimplePageMaster(index, isFirstPage, true, isBlank, false);
         }
         Page page = new Page(spm, index, pageNumberString, isBlank, spanAll, isPagePositionOnly);
         //Set unique key obtained from the AreaTreeHandler
index 6f1a187526a026fce6868e4de647116f0ec5ba45..27ff94f7c79f8f4064faf44afd037500bdc6e672 100644 (file)
@@ -141,6 +141,10 @@ public final class MutableConfig implements FopFactoryConfig {
         return delegate.isSimpleLineBreaking();
     }
 
+    public boolean isSkipPagePositionOnlyAllowed() {
+        return delegate.isSkipPagePositionOnlyAllowed();
+    }
+
     public Map<String, String> getHyphenationPatternNames() {
         return delegate.getHyphenationPatternNames();
     }
index 7048a9fd94538089db9c302a44c20babe9a49891..daf4b50dc1bf4020b4e2b1afaa281fa12b9bbde3 100644 (file)
@@ -125,6 +125,7 @@ public class TestAssistant {
         builder.getFontManager().setBase14KerningEnabled(isBase14KerningEnabled(testDoc));
         builder.setTableBorderOverpaint(isTableBorderOverpaint(testDoc));
         builder.setSimpleLineBreaking(isSimpleLineBreaking(testDoc));
+        builder.setSkipPagePositionOnlyAllowed(isSkipPagePositionOnlyAllowed(testDoc));
         return builder.build();
     }
 
@@ -169,6 +170,15 @@ public class TestAssistant {
         }
     }
 
+    private boolean isSkipPagePositionOnlyAllowed(Document testDoc) {
+        try {
+            String s = eval(testDoc, "/testcase/cfg/skip-page-position-only-allowed");
+            return !"false".equalsIgnoreCase(s);
+        } catch (XPathExpressionException e) {
+            throw new RuntimeException("Error while evaluating XPath expression", e);
+        }
+    }
+
     /**
      * Loads a test case into a DOM document.
      * @param testFile the test file
diff --git a/fop/test/layoutengine/standard-testcases/page-position_only_4.xml b/fop/test/layoutengine/standard-testcases/page-position_only_4.xml
new file mode 100644 (file)
index 0000000..9dd3aee
--- /dev/null
@@ -0,0 +1,105 @@
+<?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>
+    <skip-page-position-only-allowed>false</skip-page-position-only-allowed>
+  </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="210mm" page-height="297mm" margin-bottom="15mm" margin-right="0mm" margin-top="0mm" margin-left="0mm">
+      <fo:region-body margin-bottom="52mm" margin-right="20mm" margin-top="35mm" margin-left="20mm" region-name="letterPageBody"/>
+      <fo:region-before region-name="letterPageFrontHeader"/>
+      <fo:region-after display-align="after" precedence="true" region-name="letterPageFooter" extent="52mm"/>
+      <fo:region-end display-align="center" region-name="letterPageRightSide" extent="5mm"/>
+    </fo:simple-page-master>
+    <fo:simple-page-master master-name="PageFront" page-width="210mm" page-height="297mm" margin-bottom="0mm" margin-right="0mm" margin-top="0mm" margin-left="0mm">
+      <fo:region-body margin-bottom="15mm" margin-top="35mm" margin-right="20mm" margin-left="20mm" region-name="letterPageBody"/>
+      <fo:region-before region-name="letterPageFrontHeader"/>
+      <fo:region-end extent="5mm" display-align="center" region-name="letterPageRightSide"/>
+    </fo:simple-page-master>
+    <fo:simple-page-master master-name="RestPages" page-width="210mm" page-height="297mm" margin-bottom="0mm" margin-right="0mm" margin-top="0mm" margin-left="0mm">
+      <fo:region-body margin-top="25mm" margin-right="20mm" margin-left="20mm" margin-bottom="15mm" region-name="letterPageBody"/>
+      <fo:region-before region-name="letterPageBackHeader"/>
+    </fo:simple-page-master>
+    <fo:simple-page-master master-name="Last_Page" page-width="210mm" page-height="297mm" margin-bottom="20mm" margin-right="0mm" margin-top="0mm" margin-left="0mm">
+      <fo:region-body margin-top="25mm" margin-bottom="120mm" margin-right="20mm" margin-left="20mm" region-name="letterPageBody"/>
+      <fo:region-before region-name="letterPageBackHeader"/>
+      <fo:region-after extent="150mm" display-align="after" precedence="true" region-name="letterPageFooter"/>
+    </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="PageFront"/>
+        <fo:conditional-page-master-reference page-position="rest" master-reference="RestPages"/>
+        <fo:conditional-page-master-reference page-position="last" master-reference="Last_Page"/>
+      </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-container height="45mm">
+        <fo:block margin-top="20mm" space-before="19mm" margin-left="18mm">
+          <fo:block font-size="10pt">Mr Markus Sample</fo:block>
+          <fo:block font-size="10pt">39 XXX Street</fo:block>
+          <fo:block font-size="10pt">MELBOURNE VIC 3000</fo:block>
+        </fo:block>
+      </fo:block-container>
+      <fo:block-container>
+        <fo:block margin-top="15mm">
+          <fo:block font-size="10pt">18 November 2022</fo:block>
+        </fo:block>
+      </fo:block-container>
+      <fo:block-container>
+        <fo:block space-before="6mm">
+          <fo:block line-height="13pt" text-align="right" space-after="0pt" space-before="3pt" font-size="10pt">Policy Type: Life Insurance</fo:block>
+          <fo:block line-height="13pt" text-align="right" space-after="0pt" space-before="3pt" font-size="10pt">Policy Number: 55553420</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="24pt" font-size="10pt">Hi Markus,</fo:block>
+          <fo:block line-height="20pt" space-after="6pt" space-before="18pt" font-size="16pt" role="H1" id="N10102">Help keep your life on track</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="3pt" font-size="10pt">Mrs Vanessa Sample recently set up an XXXX Life Insurance policy and listed you as a life insured. To help us set up the policy some of your personal information was provided.</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="3pt" font-size="10pt">We have enclosed this information. A copy of the policy documentation has been sent to Mrs Vanessa Sample, as the Policy Owner, but to protect your privacy we have not shared any of your sensitive information.</fo:block>
+          <fo:block line-height="15pt" space-after="3pt" space-before="12pt" font-size="13pt" keep-with-next.within-page="always" role="H2" id="N1014F">We value your privacy</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="3pt" font-size="10pt">The ways in which your personal information is collected, used, secured and disclosed, are set out in the respective privacy policies of XXXX (as the product distributor) and xxx (as the product issuer). You can either view these online at xxxx.com.au/lifeprivacy and xxx.com.au/privacy or call 1300 209 088 to request a printed copy free of charge.</fo:block>
+          <fo:block line-height="15pt" space-after="3pt" space-before="12pt" font-size="13pt" keep-with-next.within-page="always" role="H2" id="N1015E">What you need to do</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="3pt" font-size="10pt">It’s important that you read the enclosed documents and ensure your details are correct otherwise it could result in us refusing a claim or cancelling the policy.</fo:block>
+          <fo:block line-height="15pt" space-after="3pt" space-before="12pt" font-size="13pt" keep-with-next.within-page="always" role="H2" id="N1016D">Our commitment to you</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="3pt" font-size="10pt">The insurer of xxxx Life Insurance is committed to the Life Insurance Code of Practice, further ensuring that you will continue to receive the highest possible quality service. Read more at xxxx.com.au/contact/code-of-practice.</fo:block>
+          <fo:block line-height="15pt" space-after="3pt" space-before="12pt" font-size="13pt" keep-with-next.within-page="always" role="H2" id="N1019E">We're here to help</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="3pt" font-size="10pt">If you have any questions or need to update your details please call us on <fo:inline keep-together.within-line="always">
+              <fo:inline keep-together.within-line="always" font-weight="700">1300 420 233</fo:inline>.</fo:inline>
+          </fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="30pt" font-size="10pt" keep-with-previous.within-page="always">Take care,</fo:block>
+          <fo:block line-height="13pt" space-after="0pt" space-before="3pt" font-size="10pt" keep-with-previous.within-page="always">The Life Insurance Team</fo:block>
+        </fo:block>
+      </fo:block-container>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>
+  </fo>
+  <checks>
+    <eval expected="2" xpath="count(//page)"/>
+    <eval expected="PageFront" xpath="/areaTree/pageSequence/pageViewport[1]/@simple-page-master-name"/>
+    <eval expected="Last_Page" xpath="/areaTree/pageSequence/pageViewport[2]/@simple-page-master-name"/>
+  </checks>
+</testcase>