Browse Source

Implementation of force-page-count property, patch by Gerhard Oettl,

somewhat rearranged by me. See bug 38087.


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@366569 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_92-beta
Simon Pepping 18 years ago
parent
commit
5c359c10e6

+ 15
- 2
src/java/org/apache/fop/area/AreaTreeHandler.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 1999-2005 The Apache Software Foundation.
* Copyright 1999-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -98,6 +98,8 @@ public class AreaTreeHandler extends FOEventHandler {
// The formatting results to be handed back to the caller.
private FormattingResults results = new FormattingResults();

private PageSequenceLayoutManager prevPageSeqLM;

private static Log log = LogFactory.getLog(AreaTreeHandler.class);

/**
@@ -266,7 +268,15 @@ public class AreaTreeHandler extends FOEventHandler {
/** @see org.apache.fop.fo.FOEventHandler */
public void startPageSequence(PageSequence pageSequence) {
rootFObj = pageSequence.getRoot();

// finish the previous pageSequence (handle force-page-count)
if (prevPageSeqLM != null) {
prevPageSeqLM.doForcePageCount(pageSequence.getInitialPageNumber());
prevPageSeqLM.finishPageSequence();
prevPageSeqLM = null;
// recalc pagenumber for the case that a new page is
// inserted by checkForcePageCount
}
pageSequence.initPageNumber();
//extension attachments from fo:root
wrapAndAddExtensionAttachments(rootFObj.getExtensionAttachments());
//extension attachments from fo:declarations
@@ -303,6 +313,9 @@ public class AreaTreeHandler extends FOEventHandler {
pageSLM = getLayoutManagerMaker().makePageSequenceLayoutManager(
this, pageSequence);
pageSLM.activateLayout();
// preserve the current PageSequenceLayoutManger for the
// force-page-count check at the beginning of the next PageSequence
prevPageSeqLM = pageSLM;
}
}


+ 15
- 3
src/java/org/apache/fop/fo/pagination/PageSequence.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 1999-2005 The Apache Software Foundation.
* Copyright 1999-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -139,7 +139,6 @@ public class PageSequence extends FObj {
new PageNumberGenerator(format, groupingSeparator, groupingSize, letterValue);

checkId(id);
initPageNumber();
getFOEventHandler().startPageSequence(this);
}

@@ -235,7 +234,7 @@ public class PageSequence extends FObj {
/**
* Initialize the current page number for the start of the page sequence.
*/
private void initPageNumber() {
public void initPageNumber() {
int pageNumberType = 0;
if (initialPageNumber.getEnum() != 0) {
@@ -511,4 +510,17 @@ public class PageSequence extends FObj {
public int getNameId() {
return FO_PAGE_SEQUENCE;
}
/**
* get the forcePageCount value
*/
public int getForcePageCount() {
return forcePageCount;
}

/**
* get the initial pagenumber property value
*/
public Numeric getInitialPageNumber() {
return initialPageNumber;
}
}

+ 74
- 2
src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 1999-2005 The Apache Software Foundation.
* Copyright 1999-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ package org.apache.fop.layoutmgr;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Numeric;

import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.area.AreaTreeModel;
@@ -145,8 +146,11 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
PageBreaker breaker = new PageBreaker(this);
int flowBPD = (int)getCurrentPV().getBodyRegion().getRemainingBPD();
breaker.doLayout(flowBPD);
finishPage();
}
public void finishPageSequence() {
pageSeq.getRoot().notifyPageSequenceFinished(currentPageNum,
(currentPageNum - startPageNum) + 1);
areaTreeHandler.notifyPageSequenceFinished(pageSeq,
@@ -888,4 +892,72 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
}
}

/*
* check if the page-number of the last page suits to the force-page-count property
*/
public void doForcePageCount(Numeric nextPageSeqInitialPageNumber) {

int forcePageCount = pageSeq.getForcePageCount();

// xsl-spec version 1.0 (15.oct 2001)
// auto | even | odd | end-on-even | end-on-odd | no-force | inherit
// auto:
// Force the last page in this page-sequence to be an odd-page
// if the initial-page-number of the next page-sequence is even.
// Force it to be an even-page
// if the initial-page-number of the next page-sequence is odd.
// If there is no next page-sequence
// or if the value of its initial-page-number is "auto" do not force any page.

// if force-page-count is auto then set the value of forcePageCount
// depending on the initial-page-number of the next page-sequence
if (forcePageCount == Constants.EN_AUTO) {
if (nextPageSeqInitialPageNumber.getEnum() != 0) {
// auto | auto-odd | auto-even
int nextPageSeqPageNumberType = nextPageSeqInitialPageNumber.getEnum();
if (nextPageSeqPageNumberType == Constants.EN_AUTO_ODD) {
forcePageCount = Constants.EN_END_ON_EVEN;
} else if (nextPageSeqPageNumberType == Constants.EN_AUTO_EVEN) {
forcePageCount = Constants.EN_END_ON_ODD;
} else { // auto
forcePageCount = Constants.EN_NO_FORCE;
}
} else { // <integer> for explicit page number
int nextPageSeqPageStart = nextPageSeqInitialPageNumber.getValue();
// spec rule
nextPageSeqPageStart = (nextPageSeqPageStart > 0) ? nextPageSeqPageStart : 1;
if (nextPageSeqPageStart % 2 == 0) { // explicit even startnumber
forcePageCount = Constants.EN_END_ON_ODD;
} else { // explicit odd startnumber
forcePageCount = Constants.EN_END_ON_EVEN;
}
}
}

if (forcePageCount == Constants.EN_EVEN) {
if ((currentPageNum - startPageNum + 1) % 2 != 0) { // we have a odd number of pages
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_ODD) {
if ((currentPageNum - startPageNum + 1) % 2 == 0) { // we have a even number of pages
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_END_ON_EVEN) {
if (currentPageNum % 2 != 0) { // we are now on a odd page
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_END_ON_ODD) {
if (currentPageNum % 2 == 0) { // we are now on a even page
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_NO_FORCE) {
// i hope: nothing special at all
}

if (curPage != null) {
finishPage();
}
}
}

+ 397
- 0
test/layoutengine/standard-testcases/page-sequence_force-page-count_1.xml View File

@@ -0,0 +1,397 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2006 The Apache Software Foundation

Licensed 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 force-page-count property. See bug 38087.
</p>
</info>
<fo>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>

<fo:simple-page-master master-name="defaultpage"
page-height="29.7cm" page-width="21cm">
<fo:region-body region-name="text"
margin-top="3cm" margin-bottom="3cm"
margin-left="3cm" margin-right="3cm"/>
<fo:region-before region-name="header"
extent="2.5cm" display-align="after"/>
<fo:region-after region-name="footer"
extent="2.5cm" display-align="after"/>
<fo:region-start extent="3cm"/>
<fo:region-end extent="2cm"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="emptypage"
page-height="29.7cm" page-width="21cm">
<fo:region-body region-name="text"
margin-top="3cm" margin-bottom="3cm"
margin-left="3cm" margin-right="3cm"/>
</fo:simple-page-master>
<fo:page-sequence-master master-name="defaultsequence">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference
blank-or-not-blank="blank" master-reference="defaultpage"/>
<fo:conditional-page-master-reference
blank-or-not-blank="not-blank" master-reference="defaultpage"/>
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>

<fo:page-sequence master-reference="defaultsequence">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
1. Pageseq: ends odd, [#] / auto / next is auto-even -> nothing
</fo:block>
<fo:block>
expl: ends on {odd|even}, {odd,even} number of pages # / force-page-count / initial-page-number -> action
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="auto-even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
2. Pageseq: ends even, [#] / auto / next is auto-even -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="auto-even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
3. Pageseq: ends even, [#] / auto / next is auto-odd -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="auto-odd">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
4. Pageseq: ends odd, [#] / auto / next is auto-odd -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="auto-odd">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
5. Pageseq: ends odd, [#] / auto / next is auto-even -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="auto-even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
6. Pageseq: ends even, [#] / auto / next is numeric even -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="20">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
5. Pageseq: ends even, [#] / auto / next is numeric even -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="24">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
6. Pageseq: ends even, [#] / auto / next is numeric odd -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="31">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
7. Pageseq: ends odd, [#] / auto / next is numeric odd -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="35"
force-page-count="end-on-even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
101. Pageseq: ends odd, [#] / end-on-even/ [next is auto] -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="end-on-even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
102a. Pageseq: see next page
</fo:block>
<fo:block break-before="page">
102b. Pageseq: ends even, [#] / end-on-even/ [next is auto] -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="end-on-odd">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
103. Pageseq: ends odd, [#] / end-on-odd/ [next is auto] -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="end-on-odd">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
104. Pageseq: ends even, [#] / end-on-odd/ [next is auto] -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
201. Pageseq: [ends], odd # / even / [next is auto] -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
202a. Pageseq: see next page
</fo:block>
<fo:block break-before="page">
13b. Pageseq: [ends], even # / even / [next is auto] -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="odd">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
203. Pageseq: [ends], odd # / odd / [next is auto] -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="odd">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
204a. Pageseq: see next page
</fo:block>
<fo:block break-before="page">
204b. Pageseq: [ends], even # / odd / [next is auto] -> addpage
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
force-page-count="no-force">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
301. Pageseq: ends even, [#] / no-force / next is auto-even -> nothing
</fo:block>
<fo:block>
Only to show the possibility of missing pagenumbers for
force-page-count="no-force".
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence"
initial-page-number="auto-even">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
302. Pageseq: dont matter, dont matter # / auto / next is auto -> nothing
</fo:block>
</fo:flow>
</fo:page-sequence>

<fo:page-sequence master-reference="defaultsequence">
<fo:static-content flow-name="header">
<fo:block text-align-last="end">
<fo:page-number/>
</fo:block>
</fo:static-content>
<fo:flow flow-name="text" font-family="Times Roman" font-size="12pt">
<fo:block>
999. Pageseq: dont matter, auto / no next
</fo:block>
</fo:flow>
</fo:page-sequence>

</fo:root>
</fo>
<checks>
<eval expected="1" xpath="//pageSequence[1]/pageViewport[1]/@nr"/>
<eval expected="2" xpath="//pageSequence[2]/pageViewport[1]/@nr"/>
<eval expected="3" xpath="//pageSequence[2]/pageViewport[2]/@nr"/>
<eval expected="4" xpath="//pageSequence[3]/pageViewport[1]/@nr"/>
<eval expected="5" xpath="//pageSequence[4]/pageViewport[1]/@nr"/>
<eval expected="6" xpath="//pageSequence[4]/pageViewport[2]/@nr"/>
<eval expected="7" xpath="//pageSequence[5]/pageViewport[1]/@nr"/>
<eval expected="8" xpath="//pageSequence[6]/pageViewport[1]/@nr"/>
<eval expected="9" xpath="//pageSequence[6]/pageViewport[2]/@nr"/>
<eval expected="20" xpath="//pageSequence[7]/pageViewport[1]/@nr"/>
<eval expected="21" xpath="//pageSequence[7]/pageViewport[2]/@nr"/>
<eval expected="24" xpath="//pageSequence[8]/pageViewport[1]/@nr"/>
<eval expected="31" xpath="//pageSequence[9]/pageViewport[1]/@nr"/>
<eval expected="32" xpath="//pageSequence[9]/pageViewport[2]/@nr"/>
<eval expected="35" xpath="//pageSequence[10]/pageViewport[1]/@nr"/>
<eval expected="36" xpath="//pageSequence[10]/pageViewport[2]/@nr"/>
<eval expected="37" xpath="//pageSequence[11]/pageViewport[1]/@nr"/>
<eval expected="38" xpath="//pageSequence[11]/pageViewport[2]/@nr"/>
<eval expected="39" xpath="//pageSequence[12]/pageViewport[1]/@nr"/>
<eval expected="40" xpath="//pageSequence[13]/pageViewport[1]/@nr"/>
<eval expected="41" xpath="//pageSequence[13]/pageViewport[2]/@nr"/>
<eval expected="42" xpath="//pageSequence[14]/pageViewport[1]/@nr"/>
<eval expected="43" xpath="//pageSequence[14]/pageViewport[2]/@nr"/>
<eval expected="44" xpath="//pageSequence[15]/pageViewport[1]/@nr"/>
<eval expected="45" xpath="//pageSequence[15]/pageViewport[2]/@nr"/>
<eval expected="46" xpath="//pageSequence[16]/pageViewport[1]/@nr"/>
<eval expected="47" xpath="//pageSequence[17]/pageViewport[1]/@nr"/>
<eval expected="48" xpath="//pageSequence[17]/pageViewport[2]/@nr"/>
<eval expected="49" xpath="//pageSequence[17]/pageViewport[3]/@nr"/>
<eval expected="50" xpath="//pageSequence[18]/pageViewport[1]/@nr"/>
<eval expected="52" xpath="//pageSequence[19]/pageViewport[1]/@nr"/>
<eval expected="53" xpath="//pageSequence[20]/pageViewport[1]/@nr"/>
<!-- blank pages, only the folio -->
<eval expected="3" xpath="//pageSequence[2]/pageViewport[2]"/>
<eval expected="6" xpath="//pageSequence[4]/pageViewport[2]"/>
<eval expected="9" xpath="//pageSequence[6]/pageViewport[2]"/>
<eval expected="21" xpath="//pageSequence[7]/pageViewport[2]"/>
<eval expected="32" xpath="//pageSequence[9]/pageViewport[2]"/>
<eval expected="36" xpath="//pageSequence[10]/pageViewport[2]"/>
<eval expected="41" xpath="//pageSequence[13]/pageViewport[2]"/>
<eval expected="43" xpath="//pageSequence[14]/pageViewport[2]"/>
<eval expected="49" xpath="//pageSequence[17]/pageViewport[3]"/>
</checks>
</testcase>

Loading…
Cancel
Save