Skip to content

Commit 36c3a39

Browse files
authored
FOP-3279: implement support for force-page-count extension attribute values doubly-odd, doubly-even, end-on-doubly-odd and end-on-doubly-even
1 parent c0b02f0 commit 36c3a39

File tree

6 files changed

+304
-1
lines changed

6 files changed

+304
-1
lines changed

fop-core/src/main/java/org/apache/fop/fo/Constants.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,14 @@ public interface Constants {
12661266
int EN_FIRST_INCLUDING_CARRYOVER = 204;
12671267
/** Enumeration constant -- for auto-toggle */
12681268
int EN_SELECT_FIRST_FITTING = 205;
1269+
/** Enumeration constant -- non-standard force-page-count property value */
1270+
int EN_DOUBLY_EVEN = 206;
1271+
/** Enumeration constant -- non-standard force-page-count property value */
1272+
int EN_END_ON_DOUBLY_EVEN = 207;
1273+
/** Enumeration constant -- non-standard force-page-count property value */
1274+
int EN_DOUBLY_ODD = 208;
1275+
/** Enumeration constant -- non-standard force-page-count property value */
1276+
int EN_END_ON_DOUBLY_ODD = 209;
12691277
/** Number of enumeration constants defined */
1270-
int ENUM_COUNT = 205;
1278+
int ENUM_COUNT = 209;
12711279
}

fop-core/src/main/java/org/apache/fop/fo/FOPropertyMapping.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,10 @@ private void createPaginationAndLayoutProperties() {
22842284
m.addEnum("odd", getEnumProperty(EN_ODD, "ODD"));
22852285
m.addEnum("end-on-even", getEnumProperty(EN_END_ON_EVEN, "END_ON_EVEN"));
22862286
m.addEnum("end-on-odd", getEnumProperty(EN_END_ON_ODD, "END_ON_ODD"));
2287+
m.addEnum("doubly-even", getEnumProperty(EN_DOUBLY_EVEN, "DOUBLY_EVEN"));
2288+
m.addEnum("end-on-doubly-even", getEnumProperty(EN_END_ON_DOUBLY_EVEN, "END_ON_DOUBLY_EVEN"));
2289+
m.addEnum("doubly-odd", getEnumProperty(EN_DOUBLY_ODD, "DOUBLY_ODD"));
2290+
m.addEnum("end-on-doubly-odd", getEnumProperty(EN_END_ON_DOUBLY_ODD, "END_ON_DOUBLY_ODD"));
22872291
m.addEnum("no-force", getEnumProperty(EN_NO_FORCE, "NO_FORCE"));
22882292
m.addEnum("auto", getEnumProperty(EN_AUTO, "AUTO"));
22892293
m.setDefault("auto");

fop-core/src/main/java/org/apache/fop/layoutmgr/AbstractPageSequenceLayoutManager.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,22 @@ public void doForcePageCount(Numeric nextPageSeqInitialPageNumber) {
377377
if (currentPageNum % 2 == 0) { // we are now on an even page
378378
curPage = makeNewPage(true);
379379
}
380+
} else if (forcePageCount == Constants.EN_DOUBLY_EVEN) {
381+
while ((this.currentPageNum - this.startPageNum + 1) % 4 != 0) {
382+
this.curPage = makeNewPage(true);
383+
}
384+
} else if (forcePageCount == Constants.EN_END_ON_DOUBLY_EVEN) {
385+
while (this.currentPageNum % 4 != 0) {
386+
this.curPage = makeNewPage(true);
387+
}
388+
} else if (forcePageCount == Constants.EN_DOUBLY_ODD) {
389+
while ((this.currentPageNum - this.startPageNum + 1) % 4 != 3) {
390+
this.curPage = makeNewPage(true);
391+
}
392+
} else if (forcePageCount == Constants.EN_END_ON_DOUBLY_ODD) {
393+
while (this.currentPageNum % 4 != 3) {
394+
this.curPage = makeNewPage(true);
395+
}
380396
} /* else if (forcePageCount == Constants.EN_NO_FORCE) {
381397
// i hope: nothing special at all
382398
} */

fop-core/src/main/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,18 @@ protected int getForcedLastPageNum(final int lastPageNum) {
268268
if (lastPageNum % 2 == 0) {
269269
forcedLastPageNum++;
270270
}
271+
} else if ((lastPageNum - startPageNum + 1) % 4 != 0
272+
&& getPageSequence().getForcePageCount() == Constants.EN_DOUBLY_EVEN) {
273+
forcedLastPageNum += 4 - (lastPageNum - startPageNum + 1) % 4;
274+
} else if (lastPageNum % 4 != 0
275+
&& getPageSequence().getForcePageCount() == Constants.EN_END_ON_DOUBLY_EVEN) {
276+
forcedLastPageNum += 4 - lastPageNum % 4;
277+
} else if ((lastPageNum - startPageNum + 1) % 4 != 3
278+
&& getPageSequence().getForcePageCount() == Constants.EN_DOUBLY_ODD) {
279+
forcedLastPageNum += 4 - (lastPageNum - startPageNum + 2) % 4;
280+
} else if (lastPageNum % 4 != 3
281+
&& getPageSequence().getForcePageCount() == Constants.EN_END_ON_DOUBLY_ODD) {
282+
forcedLastPageNum += 4 - (lastPageNum + 1) % 4;
271283
}
272284
return forcedLastPageNum;
273285
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one or more
4+
contributor license agreements. See the NOTICE file distributed with
5+
this work for additional information regarding copyright ownership.
6+
The ASF licenses this file to You under the Apache License, Version 2.0
7+
(the "License"); you may not use this file except in compliance with
8+
the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-->
18+
<!-- $Id$ -->
19+
<testcase>
20+
<info>
21+
<p>
22+
This test checks the non-standard value doubly-even and
23+
end-on-doubly-even of the force-page-count property.
24+
</p>
25+
</info>
26+
<fo>
27+
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
28+
<fo:layout-master-set>
29+
<fo:simple-page-master master-name="first" page-width="210mm" page-height="297mm">
30+
<fo:region-body background-color="red" margin-bottom="2cm"/>
31+
<fo:region-after extent="2cm" region-name="bottom-first"/>
32+
</fo:simple-page-master>
33+
<fo:simple-page-master master-name="rest" page-width="210mm" page-height="297mm">
34+
<fo:region-body background-color="yellow" margin-bottom="2cm"/>
35+
<fo:region-after extent="2cm" region-name="bottom-rest"/>
36+
</fo:simple-page-master>
37+
<fo:simple-page-master master-name="last" page-width="210mm" page-height="297mm">
38+
<fo:region-body background-color="green" margin-bottom="2cm"/>
39+
<fo:region-after extent="2cm" region-name="bottom-last"/>
40+
</fo:simple-page-master>
41+
<fo:page-sequence-master master-name="ps">
42+
<fo:repeatable-page-master-alternatives>
43+
<fo:conditional-page-master-reference master-reference="first" page-position="first" odd-or-even="any"/>
44+
<fo:conditional-page-master-reference master-reference="rest" page-position="rest" odd-or-even="any"/>
45+
<fo:conditional-page-master-reference master-reference="last" page-position="last" odd-or-even="any"/>
46+
</fo:repeatable-page-master-alternatives>
47+
</fo:page-sequence-master>
48+
</fo:layout-master-set>
49+
<fo:page-sequence master-reference="ps">
50+
<fo:static-content flow-name="bottom-first">
51+
<fo:block border-top-width=".1mm" border-top-style="solid">
52+
first-<fo:page-number/>
53+
</fo:block>
54+
</fo:static-content>
55+
<fo:static-content flow-name="bottom-rest">
56+
<fo:block border-top-width=".1mm" border-top-style="solid">
57+
rest-<fo:page-number/>
58+
</fo:block>
59+
</fo:static-content>
60+
<fo:static-content flow-name="bottom-last">
61+
<fo:block border-top-width=".1mm" border-top-style="solid">
62+
last-<fo:page-number/>
63+
</fo:block>
64+
</fo:static-content>
65+
<fo:flow flow-name="xsl-region-body">
66+
<fo:block>Page 1</fo:block>
67+
</fo:flow>
68+
</fo:page-sequence>
69+
<fo:page-sequence master-reference="ps" force-page-count="doubly-even">
70+
<fo:static-content flow-name="bottom-first">
71+
<fo:block border-top-width=".1mm" border-top-style="solid">
72+
first-<fo:page-number/>
73+
</fo:block>
74+
</fo:static-content>
75+
<fo:static-content flow-name="bottom-rest">
76+
<fo:block border-top-width=".1mm" border-top-style="solid">
77+
rest-<fo:page-number/>
78+
</fo:block>
79+
</fo:static-content>
80+
<fo:static-content flow-name="bottom-last">
81+
<fo:block border-top-width=".1mm" border-top-style="solid">
82+
last-<fo:page-number/>
83+
</fo:block>
84+
</fo:static-content>
85+
<fo:flow flow-name="xsl-region-body">
86+
<fo:block>Page 2</fo:block>
87+
</fo:flow>
88+
</fo:page-sequence>
89+
<fo:page-sequence master-reference="ps" force-page-count="end-on-doubly-even">
90+
<fo:static-content flow-name="bottom-first">
91+
<fo:block border-top-width=".1mm" border-top-style="solid">
92+
first-<fo:page-number/>
93+
</fo:block>
94+
</fo:static-content>
95+
<fo:static-content flow-name="bottom-rest">
96+
<fo:block border-top-width=".1mm" border-top-style="solid">
97+
rest-<fo:page-number/>
98+
</fo:block>
99+
</fo:static-content>
100+
<fo:static-content flow-name="bottom-last">
101+
<fo:block border-top-width=".1mm" border-top-style="solid">
102+
last-<fo:page-number/>
103+
</fo:block>
104+
</fo:static-content>
105+
<fo:flow flow-name="xsl-region-body">
106+
<fo:block>Page 6</fo:block>
107+
</fo:flow>
108+
</fo:page-sequence>
109+
</fo:root>
110+
</fo>
111+
<checks>
112+
<eval expected="first" xpath="(//pageViewport)[1]/@simple-page-master-name"/>
113+
<eval expected="first" xpath="(//pageViewport)[2]/@simple-page-master-name"/>
114+
<eval expected="rest" xpath="(//pageViewport)[3]/@simple-page-master-name"/>
115+
<eval expected="rest" xpath="(//pageViewport)[4]/@simple-page-master-name"/>
116+
<eval expected="last" xpath="(//pageViewport)[5]/@simple-page-master-name"/>
117+
<eval expected="first" xpath="(//pageViewport)[6]/@simple-page-master-name"/>
118+
<eval expected="rest" xpath="(//pageViewport)[7]/@simple-page-master-name"/>
119+
<eval expected="last" xpath="(//pageViewport)[8]/@simple-page-master-name"/>
120+
<eval expected="8" xpath="count(//pageViewport)"/>
121+
</checks>
122+
</testcase>
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one or more
4+
contributor license agreements. See the NOTICE file distributed with
5+
this work for additional information regarding copyright ownership.
6+
The ASF licenses this file to You under the Apache License, Version 2.0
7+
(the "License"); you may not use this file except in compliance with
8+
the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-->
18+
<!-- $Id$ -->
19+
<testcase>
20+
<info>
21+
<p>
22+
This test checks the non-standard value doubly-odd and end-on-doubly-odd
23+
of the force-page-count property.
24+
</p>
25+
</info>
26+
<fo>
27+
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
28+
<fo:layout-master-set>
29+
<fo:simple-page-master master-name="first" page-width="210mm" page-height="297mm">
30+
<fo:region-body background-color="red" margin-bottom="2cm"/>
31+
<fo:region-after extent="2cm" region-name="bottom-first"/>
32+
</fo:simple-page-master>
33+
<fo:simple-page-master master-name="rest" page-width="210mm" page-height="297mm">
34+
<fo:region-body background-color="yellow" margin-bottom="2cm"/>
35+
<fo:region-after extent="2cm" region-name="bottom-rest"/>
36+
</fo:simple-page-master>
37+
<fo:simple-page-master master-name="last" page-width="210mm" page-height="297mm">
38+
<fo:region-body background-color="green" margin-bottom="2cm"/>
39+
<fo:region-after extent="2cm" region-name="bottom-last"/>
40+
</fo:simple-page-master>
41+
<fo:page-sequence-master master-name="ps">
42+
<fo:repeatable-page-master-alternatives>
43+
<fo:conditional-page-master-reference master-reference="first" page-position="first" odd-or-even="any"/>
44+
<fo:conditional-page-master-reference master-reference="rest" page-position="rest" odd-or-even="any"/>
45+
<fo:conditional-page-master-reference master-reference="last" page-position="last" odd-or-even="any"/>
46+
</fo:repeatable-page-master-alternatives>
47+
</fo:page-sequence-master>
48+
</fo:layout-master-set>
49+
<fo:page-sequence master-reference="ps">
50+
<fo:static-content flow-name="bottom-first">
51+
<fo:block border-top-width=".1mm" border-top-style="solid">
52+
first-<fo:page-number/>
53+
</fo:block>
54+
</fo:static-content>
55+
<fo:static-content flow-name="bottom-rest">
56+
<fo:block border-top-width=".1mm" border-top-style="solid">
57+
rest-<fo:page-number/>
58+
</fo:block>
59+
</fo:static-content>
60+
<fo:static-content flow-name="bottom-last">
61+
<fo:block border-top-width=".1mm" border-top-style="solid">
62+
last-<fo:page-number/>
63+
</fo:block>
64+
</fo:static-content>
65+
<fo:flow flow-name="xsl-region-body">
66+
<fo:block>Page 1</fo:block>
67+
</fo:flow>
68+
</fo:page-sequence>
69+
<fo:page-sequence master-reference="ps" force-page-count="doubly-odd">
70+
<fo:static-content flow-name="bottom-first">
71+
<fo:block border-top-width=".1mm" border-top-style="solid">
72+
first-<fo:page-number/>
73+
</fo:block>
74+
</fo:static-content>
75+
<fo:static-content flow-name="bottom-rest">
76+
<fo:block border-top-width=".1mm" border-top-style="solid">
77+
rest-<fo:page-number/>
78+
</fo:block>
79+
</fo:static-content>
80+
<fo:static-content flow-name="bottom-last">
81+
<fo:block border-top-width=".1mm" border-top-style="solid">
82+
last-<fo:page-number/>
83+
</fo:block>
84+
</fo:static-content>
85+
<fo:flow flow-name="xsl-region-body">
86+
<fo:block>Page 2</fo:block>
87+
</fo:flow>
88+
</fo:page-sequence>
89+
<fo:page-sequence master-reference="ps">
90+
<fo:static-content flow-name="bottom-first">
91+
<fo:block border-top-width=".1mm" border-top-style="solid">
92+
first-<fo:page-number/>
93+
</fo:block>
94+
</fo:static-content>
95+
<fo:static-content flow-name="bottom-rest">
96+
<fo:block border-top-width=".1mm" border-top-style="solid">
97+
rest-<fo:page-number/>
98+
</fo:block>
99+
</fo:static-content>
100+
<fo:static-content flow-name="bottom-last">
101+
<fo:block border-top-width=".1mm" border-top-style="solid">
102+
last-<fo:page-number/>
103+
</fo:block>
104+
</fo:static-content>
105+
<fo:flow flow-name="xsl-region-body">
106+
<fo:block>Page 5</fo:block>
107+
</fo:flow>
108+
</fo:page-sequence>
109+
<fo:page-sequence master-reference="ps" force-page-count="end-on-doubly-odd">
110+
<fo:static-content flow-name="bottom-first">
111+
<fo:block border-top-width=".1mm" border-top-style="solid">
112+
first-<fo:page-number/>
113+
</fo:block>
114+
</fo:static-content>
115+
<fo:static-content flow-name="bottom-rest">
116+
<fo:block border-top-width=".1mm" border-top-style="solid">
117+
rest-<fo:page-number/>
118+
</fo:block>
119+
</fo:static-content>
120+
<fo:static-content flow-name="bottom-last">
121+
<fo:block border-top-width=".1mm" border-top-style="solid">
122+
last-<fo:page-number/>
123+
</fo:block>
124+
</fo:static-content>
125+
<fo:flow flow-name="xsl-region-body">
126+
<fo:block>Page 6</fo:block>
127+
</fo:flow>
128+
</fo:page-sequence>
129+
</fo:root>
130+
</fo>
131+
<checks>
132+
<eval expected="first" xpath="(//pageViewport)[1]/@simple-page-master-name"/>
133+
<eval expected="first" xpath="(//pageViewport)[2]/@simple-page-master-name"/>
134+
<eval expected="rest" xpath="(//pageViewport)[3]/@simple-page-master-name"/>
135+
<eval expected="last" xpath="(//pageViewport)[4]/@simple-page-master-name"/>
136+
<eval expected="first" xpath="(//pageViewport)[5]/@simple-page-master-name"/>
137+
<eval expected="first" xpath="(//pageViewport)[6]/@simple-page-master-name"/>
138+
<eval expected="last" xpath="(//pageViewport)[7]/@simple-page-master-name"/>
139+
<eval expected="7" xpath="count(//pageViewport)"/>
140+
</checks>
141+
</testcase>

0 commit comments

Comments
 (0)