From f003c0f4494db056a0b19ef3ff88e463b0ac7f1f Mon Sep 17 00:00:00 2001 From: Matthias Reischenbacher Date: Sun, 12 Oct 2025 15:55:08 -0300 Subject: [PATCH] FOP-3279: implement support for force-page-count extension attribute values doubly-odd, doubly-even, end-on-doubly-odd and end-on-doubly-even --- .../java/org/apache/fop/fo/Constants.java | 10 +- .../org/apache/fop/fo/FOPropertyMapping.java | 4 + .../AbstractPageSequenceLayoutManager.java | 16 ++ .../layoutmgr/PageSequenceLayoutManager.java | 12 ++ ...-sequence-force-page-count-doubly-even.xml | 122 +++++++++++++++ ...e-sequence-force-page-count-doubly-odd.xml | 141 ++++++++++++++++++ 6 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-even.xml create mode 100644 fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-odd.xml diff --git a/fop-core/src/main/java/org/apache/fop/fo/Constants.java b/fop-core/src/main/java/org/apache/fop/fo/Constants.java index 48108102170..997ac0246f6 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/Constants.java +++ b/fop-core/src/main/java/org/apache/fop/fo/Constants.java @@ -1266,6 +1266,14 @@ public interface Constants { int EN_FIRST_INCLUDING_CARRYOVER = 204; /** Enumeration constant -- for auto-toggle */ int EN_SELECT_FIRST_FITTING = 205; + /** Enumeration constant -- non-standard force-page-count property value */ + int EN_DOUBLY_EVEN = 206; + /** Enumeration constant -- non-standard force-page-count property value */ + int EN_END_ON_DOUBLY_EVEN = 207; + /** Enumeration constant -- non-standard force-page-count property value */ + int EN_DOUBLY_ODD = 208; + /** Enumeration constant -- non-standard force-page-count property value */ + int EN_END_ON_DOUBLY_ODD = 209; /** Number of enumeration constants defined */ - int ENUM_COUNT = 205; + int ENUM_COUNT = 209; } diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java b/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java index 4fc5c4df2f3..9328581c855 100644 --- a/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java @@ -2284,6 +2284,10 @@ private void createPaginationAndLayoutProperties() { m.addEnum("odd", getEnumProperty(EN_ODD, "ODD")); m.addEnum("end-on-even", getEnumProperty(EN_END_ON_EVEN, "END_ON_EVEN")); m.addEnum("end-on-odd", getEnumProperty(EN_END_ON_ODD, "END_ON_ODD")); + m.addEnum("doubly-even", getEnumProperty(EN_DOUBLY_EVEN, "DOUBLY_EVEN")); + m.addEnum("end-on-doubly-even", getEnumProperty(EN_END_ON_DOUBLY_EVEN, "END_ON_DOUBLY_EVEN")); + m.addEnum("doubly-odd", getEnumProperty(EN_DOUBLY_ODD, "DOUBLY_ODD")); + m.addEnum("end-on-doubly-odd", getEnumProperty(EN_END_ON_DOUBLY_ODD, "END_ON_DOUBLY_ODD")); m.addEnum("no-force", getEnumProperty(EN_NO_FORCE, "NO_FORCE")); m.addEnum("auto", getEnumProperty(EN_AUTO, "AUTO")); m.setDefault("auto"); diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java index dd30b8abf74..ad2112bbcea 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java @@ -377,6 +377,22 @@ public void doForcePageCount(Numeric nextPageSeqInitialPageNumber) { if (currentPageNum % 2 == 0) { // we are now on an even page curPage = makeNewPage(true); } + } else if (forcePageCount == Constants.EN_DOUBLY_EVEN) { + while ((this.currentPageNum - this.startPageNum + 1) % 4 != 0) { + this.curPage = makeNewPage(true); + } + } else if (forcePageCount == Constants.EN_END_ON_DOUBLY_EVEN) { + while (this.currentPageNum % 4 != 0) { + this.curPage = makeNewPage(true); + } + } else if (forcePageCount == Constants.EN_DOUBLY_ODD) { + while ((this.currentPageNum - this.startPageNum + 1) % 4 != 3) { + this.curPage = makeNewPage(true); + } + } else if (forcePageCount == Constants.EN_END_ON_DOUBLY_ODD) { + while (this.currentPageNum % 4 != 3) { + this.curPage = makeNewPage(true); + } } /* else if (forcePageCount == Constants.EN_NO_FORCE) { // i hope: nothing special at all } */ diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java index 32c7661bd9e..87d7ba40ed1 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java @@ -268,6 +268,18 @@ protected int getForcedLastPageNum(final int lastPageNum) { if (lastPageNum % 2 == 0) { forcedLastPageNum++; } + } else if ((lastPageNum - startPageNum + 1) % 4 != 0 + && getPageSequence().getForcePageCount() == Constants.EN_DOUBLY_EVEN) { + forcedLastPageNum += 4 - (lastPageNum - startPageNum + 1) % 4; + } else if (lastPageNum % 4 != 0 + && getPageSequence().getForcePageCount() == Constants.EN_END_ON_DOUBLY_EVEN) { + forcedLastPageNum += 4 - lastPageNum % 4; + } else if ((lastPageNum - startPageNum + 1) % 4 != 3 + && getPageSequence().getForcePageCount() == Constants.EN_DOUBLY_ODD) { + forcedLastPageNum += 4 - (lastPageNum - startPageNum + 2) % 4; + } else if (lastPageNum % 4 != 3 + && getPageSequence().getForcePageCount() == Constants.EN_END_ON_DOUBLY_ODD) { + forcedLastPageNum += 4 - (lastPageNum + 1) % 4; } return forcedLastPageNum; } diff --git a/fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-even.xml b/fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-even.xml new file mode 100644 index 00000000000..83e3ffee574 --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-even.xml @@ -0,0 +1,122 @@ + + + + + +

+ This test checks the non-standard value doubly-even and + end-on-doubly-even of the force-page-count property. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + first- + + + + + rest- + + + + + last- + + + + Page 1 + + + + + + first- + + + + + rest- + + + + + last- + + + + Page 2 + + + + + + first- + + + + + rest- + + + + + last- + + + + Page 6 + + + + + + + + + + + + + + + +
diff --git a/fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-odd.xml b/fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-odd.xml new file mode 100644 index 00000000000..a8fccd81c47 --- /dev/null +++ b/fop/test/layoutengine/standard-testcases/page-sequence-force-page-count-doubly-odd.xml @@ -0,0 +1,141 @@ + + + + + +

+ This test checks the non-standard value doubly-odd and end-on-doubly-odd + of the force-page-count property. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + first- + + + + + rest- + + + + + last- + + + + Page 1 + + + + + + first- + + + + + rest- + + + + + last- + + + + Page 2 + + + + + + first- + + + + + rest- + + + + + last- + + + + Page 5 + + + + + + first- + + + + + rest- + + + + + last- + + + + Page 6 + + + + + + + + + + + + + + +