git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_14_0_regions@193733 13f79535-47bb-0310-9956-ffa450edef68fop-0_14_0_regions
@@ -55,8 +55,7 @@ import org.apache.fop.fo.properties.*; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.messaging.MessageHandler; | |||
public class ConditionalPageMasterReference | |||
extends PageMasterReference implements SubSequenceSpecifier { | |||
public class ConditionalPageMasterReference extends FObj { | |||
public static class Maker extends FObj.Maker { | |||
public FObj make(FObj parent, PropertyList propertyList) | |||
@@ -103,7 +102,8 @@ public class ConditionalPageMasterReference | |||
} | |||
} | |||
protected boolean isValid( int currentPageNumber, boolean thisIsFirstPage ) | |||
protected boolean isValid( int currentPageNumber, boolean thisIsFirstPage, | |||
boolean isEmptyPage ) | |||
{ | |||
// page-position | |||
boolean okOnPagePosition = true; // default is 'any' | |||
@@ -137,9 +137,19 @@ public class ConditionalPageMasterReference | |||
okOnOddOrEven = false; | |||
} | |||
// no check for blankness at the moment | |||
return (okOnOddOrEven && okOnPagePosition); | |||
// experimental check for blank-or-not-blank | |||
boolean okOnBlankOrNotBlank = true; // default is 'any' | |||
int bnb = getBlankOrNotBlank(); | |||
if ((BlankOrNotBlank.BLANK == bnb) && !isEmptyPage) | |||
{ | |||
okOnBlankOrNotBlank = false; | |||
} | |||
else if ((BlankOrNotBlank.NOT_BLANK == bnb) && isEmptyPage) | |||
{ | |||
okOnBlankOrNotBlank = false; | |||
} | |||
return (okOnOddOrEven && okOnPagePosition && okOnBlankOrNotBlank); | |||
} | |||
protected void setPagePosition( int pagePosition ) | |||
@@ -171,4 +181,15 @@ public class ConditionalPageMasterReference | |||
{ | |||
return this.blankOrNotBlank; | |||
} | |||
public void setMasterName( String masterName ) | |||
{ | |||
this.masterName = masterName; | |||
} | |||
public String getMasterName() | |||
{ | |||
return this.masterName; | |||
} | |||
} |
@@ -52,6 +52,7 @@ package org.apache.fop.fo.pagination; | |||
// FOP | |||
import org.apache.fop.fo.*; | |||
import org.apache.fop.fo.flow.Flow; | |||
import org.apache.fop.fo.properties.*; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.layout.PageMaster; | |||
@@ -80,6 +81,7 @@ public class LayoutMasterSet extends FObj { | |||
private Root root; | |||
private String currentPageMasterName; | |||
private Hashtable allRegions; | |||
private PageSequenceMaster lastPageSequenceMaster; | |||
protected LayoutMasterSet(FObj parent, PropertyList propertyList) | |||
throws FOPException { | |||
@@ -101,7 +103,7 @@ public class LayoutMasterSet extends FObj { | |||
} | |||
public PageMaster getNextPageMaster( String pageSequenceName, | |||
int currentPageNumber, boolean thisIsFirstPage ) | |||
int currentPageNumber, boolean thisIsFirstPage, boolean isEmptyPage ) | |||
throws FOPException | |||
{ | |||
PageMaster pm = null; | |||
@@ -109,7 +111,9 @@ public class LayoutMasterSet extends FObj { | |||
PageSequenceMaster psm = getPageSequenceMaster( pageSequenceName ); | |||
if (null != psm) | |||
{ | |||
pm = psm.getNextPageMaster( currentPageNumber, thisIsFirstPage ); | |||
pm = psm.getNextPageMaster( currentPageNumber, thisIsFirstPage, | |||
isEmptyPage ); | |||
lastPageSequenceMaster = psm; | |||
// call in this sequence | |||
currentPageMasterName = psm.getNextPageMasterName(); | |||
} else { | |||
@@ -214,4 +218,26 @@ public class LayoutMasterSet extends FObj { | |||
} | |||
} | |||
} | |||
public void resetPageMasters() | |||
{ | |||
for (Enumeration e = pageSequenceMasters.elements(); e.hasMoreElements(); ) | |||
{ | |||
((PageSequenceMaster)e.nextElement()).reset(); | |||
} | |||
} | |||
public boolean isFlowForMasterNameDone( String masterName ) | |||
{ | |||
// parameter is master-name of PMR; we need to locate PM | |||
// referenced by this, and determine whether flow(s) are OK | |||
SimplePageMaster spm = getSimplePageMaster( masterName ); | |||
PageSequence ps = this.root.getCurrentPageSequence(); | |||
Flow flow = ps.getFlow( masterName ); | |||
if ((null == flow) || flow.getCurrentStatus().isIncomplete()) | |||
return false; | |||
else | |||
return true; | |||
} | |||
} |
@@ -174,7 +174,9 @@ public class PageSequence extends FObj | |||
masterName = ((MasterName) this.properties.get("master-name")).getString(); | |||
} | |||
protected Page makePage(AreaTree areaTree) throws FOPException { | |||
protected Page makePage(AreaTree areaTree, int firstAvailPageNumber, | |||
boolean isFirstPage, boolean isEmptyPage) | |||
throws FOPException { | |||
// layout this page sequence | |||
// while there is still stuff in the flow, ask the | |||
@@ -183,7 +185,7 @@ public class PageSequence extends FObj | |||
// page number is 0-indexed | |||
PageMaster pageMaster = | |||
this.layoutMasterSet.getNextPageMaster( | |||
masterName, currentPageNumber, thisIsFirstPage ); | |||
masterName, firstAvailPageNumber, isFirstPage, isEmptyPage ); | |||
// store the current 'master-name' for access by format() | |||
currentPageMasterName = this.layoutMasterSet.getCurrentPageMasterName(); | |||
@@ -200,12 +202,19 @@ public class PageSequence extends FObj | |||
public void format(AreaTree areaTree) throws FOPException { | |||
Status status = new Status(Status.OK); | |||
this.layoutMasterSet.resetPageMasters(); | |||
do | |||
{ | |||
currentPage = makePage(areaTree); | |||
// makePage() moved to after the page-number computations, | |||
// but store the page-number at this point for that method, | |||
// since we want the 'current' current page-number... | |||
int firstAvailPageNumber = this.runningPageNumberCounter; | |||
boolean tempIsFirstPage = false; | |||
if ( thisIsFirstPage ) | |||
{ | |||
tempIsFirstPage = thisIsFirstPage; | |||
if ( pageNumberType==AUTO ) | |||
{ | |||
this.currentPageNumber=this.runningPageNumberCounter; | |||
@@ -228,8 +237,30 @@ public class PageSequence extends FObj | |||
} | |||
thisIsFirstPage=false; | |||
} | |||
currentPage.setNumber(++this.currentPageNumber); | |||
this.currentPageNumber++; | |||
// deliberately moved down here so page-number calculations | |||
// are complete; | |||
// compute flag for 'blank-or-not-blank' | |||
boolean isEmptyPage = false; | |||
if ( (status.getCode() == Status.FORCE_PAGE_BREAK_EVEN) && | |||
((currentPageNumber % 2) == 1) ) | |||
{ | |||
isEmptyPage = true; | |||
} | |||
else if ( (status.getCode() == Status.FORCE_PAGE_BREAK_ODD) && | |||
((currentPageNumber % 2) == 0) ) | |||
{ | |||
isEmptyPage = true; | |||
} | |||
else | |||
{ | |||
isEmptyPage = false; | |||
} | |||
currentPage = makePage(areaTree, firstAvailPageNumber, tempIsFirstPage, isEmptyPage); | |||
currentPage.setNumber(this.currentPageNumber); | |||
this.runningPageNumberCounter=this.currentPageNumber; | |||
MessageHandler.log(" [" + currentPageNumber); | |||
@@ -266,12 +297,10 @@ public class PageSequence extends FObj | |||
if ( (status.getCode() == Status.FORCE_PAGE_BREAK_EVEN) && | |||
((currentPageNumber % 2) == 1) ) | |||
{ | |||
// linkage to ConditionalPageMasterReference for blank pages? | |||
} | |||
else if ( (status.getCode() == Status.FORCE_PAGE_BREAK_ODD) && | |||
((currentPageNumber % 2) == 0) ) | |||
{ | |||
// linkage to ConditionalPageMasterReference for blank pages? | |||
} | |||
else | |||
{ | |||
@@ -378,8 +407,16 @@ public class PageSequence extends FObj | |||
boolean isIncomplete = false; | |||
for (Enumeration e = flows.elements(); e.hasMoreElements(); ) | |||
{ | |||
isIncomplete = ((Flow)e.nextElement()).getCurrentStatus().isIncomplete(); | |||
Flow flow = (Flow)e.nextElement(); | |||
Status status = flow.getCurrentStatus(); | |||
isIncomplete |= status.isIncomplete(); | |||
} | |||
return isIncomplete; | |||
} | |||
public Flow getFlow( String flowName ) | |||
{ | |||
return (Flow)flows.get( flowName ); | |||
} | |||
} |
@@ -60,6 +60,7 @@ import org.apache.fop.messaging.MessageHandler; | |||
// Java | |||
import java.util.Vector; | |||
import java.util.Enumeration; | |||
public class PageSequenceMaster extends FObj { | |||
@@ -77,6 +78,7 @@ public class PageSequenceMaster extends FObj { | |||
LayoutMasterSet layoutMasterSet; | |||
Vector subSequenceSpecifiers; | |||
SubSequenceSpecifier currentPmr; | |||
private int ssIndex; | |||
// SimplePageMasters are not exposed outside this class. Hence, this | |||
// variable tracks the current master-name for the last SPM. | |||
@@ -94,6 +96,7 @@ public class PageSequenceMaster extends FObj { | |||
this.name = "fo:page-sequence-master"; | |||
subSequenceSpecifiers = new Vector(); | |||
ssIndex = 0; | |||
if (parent.getName().equals("fo:layout-master-set")) { | |||
this.layoutMasterSet = (LayoutMasterSet) parent; | |||
@@ -118,12 +121,15 @@ public class PageSequenceMaster extends FObj { | |||
protected SubSequenceSpecifier getNextSubsequenceSpecifier() | |||
{ | |||
currentPmr = (SubSequenceSpecifier)subSequenceSpecifiers.elementAt( 0 ); | |||
subSequenceSpecifiers.removeElementAt(0); | |||
return currentPmr; | |||
if (ssIndex == subSequenceSpecifiers.size()) | |||
return null; | |||
SubSequenceSpecifier pmr = (SubSequenceSpecifier)subSequenceSpecifiers.elementAt( ssIndex ); | |||
ssIndex++; | |||
return pmr; | |||
} | |||
public PageMaster getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage ) | |||
public PageMaster getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage, | |||
boolean isEmptyPage ) | |||
{ | |||
if (null == currentPmr) | |||
{ | |||
@@ -131,17 +137,18 @@ public class PageSequenceMaster extends FObj { | |||
} | |||
String nextPageMaster = | |||
currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage ); | |||
currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage, isEmptyPage ); | |||
if (null == nextPageMaster) | |||
{ | |||
currentPmr = getNextSubsequenceSpecifier(); | |||
nextPageMaster = | |||
currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage ); | |||
currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage, isEmptyPage ); | |||
} | |||
SimplePageMaster spm = this.layoutMasterSet.getSimplePageMaster( nextPageMaster ); | |||
currentPageMasterName = spm.getMasterName(); // store for outside access | |||
return spm.getPageMaster(); | |||
} | |||
@@ -154,4 +161,23 @@ public class PageSequenceMaster extends FObj { | |||
{ | |||
return currentPageMasterName; | |||
} | |||
public void reset() | |||
{ | |||
for (Enumeration e = subSequenceSpecifiers.elements(); e.hasMoreElements(); ) | |||
{ | |||
((SubSequenceSpecifier)e.nextElement()).reset(); | |||
} | |||
ssIndex = 0; | |||
} | |||
public boolean isFlowForMasterNameDone( String masterName ) | |||
{ | |||
// parameter is master-name of PMR; we need to locate PM | |||
// referenced by this, and determine whether flow(s) are OK | |||
if (this.layoutMasterSet.isFlowForMasterNameDone( masterName )) | |||
return true; | |||
else | |||
return false; | |||
} | |||
} |
@@ -72,14 +72,14 @@ public class RepeatablePageMasterAlternatives extends FObj | |||
} | |||
private PageSequenceMaster pageSequenceMaster; | |||
private int maximumRepeats; | |||
private int numberConsumed = 0; | |||
private int BOUNDED = 1; | |||
private int UNBOUNDED = 0; | |||
private int state; | |||
private int boundedness; | |||
private Vector conditionalPageMasterRefs; | |||
public RepeatablePageMasterAlternatives(FObj parent, PropertyList propertyList) | |||
@@ -103,22 +103,24 @@ public class RepeatablePageMasterAlternatives extends FObj | |||
{ | |||
try { | |||
setMaximumRepeats( Integer.parseInt( mr ) ); | |||
this.state = BOUNDED; | |||
this.boundedness = BOUNDED; | |||
} catch (NumberFormatException nfe) { | |||
throw new FOPException( "Invalid number for " + | |||
"'maximum-repeats' property" ); | |||
} | |||
} else { | |||
this.state = UNBOUNDED; // unbounded | |||
this.boundedness = UNBOUNDED; // unbounded | |||
} | |||
} | |||
public String getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage ) { | |||
public String getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage, | |||
boolean isEmptyPage ) { | |||
String pm = null; | |||
if (this.state == BOUNDED ) { | |||
if (this.boundedness == BOUNDED ) { | |||
if (numberConsumed < getMaximumRepeats()) { | |||
numberConsumed++; | |||
} else { | |||
@@ -129,16 +131,19 @@ public class RepeatablePageMasterAlternatives extends FObj | |||
for (int i = 0; i < conditionalPageMasterRefs.size(); i++) | |||
{ | |||
ConditionalPageMasterReference cpmr = | |||
(ConditionalPageMasterReference)conditionalPageMasterRefs.get(i); | |||
(ConditionalPageMasterReference)conditionalPageMasterRefs.elementAt(i); | |||
// 0-indexed page number | |||
if (cpmr.isValid(currentPageNumber + 1, thisIsFirstPage)) | |||
if (cpmr.isValid(currentPageNumber + 1, thisIsFirstPage, isEmptyPage )) | |||
{ | |||
pm = cpmr.getMasterName(); | |||
break; | |||
} | |||
} | |||
if ((pm != null) && this.pageSequenceMaster.isFlowForMasterNameDone( pm )) | |||
pm = null; | |||
return pm; | |||
} | |||
@@ -159,4 +164,8 @@ public class RepeatablePageMasterAlternatives extends FObj | |||
this.conditionalPageMasterRefs.addElement( cpmr ); | |||
} | |||
public void reset() | |||
{ | |||
numberConsumed = 0; | |||
} | |||
} |
@@ -53,7 +53,7 @@ package org.apache.fop.fo.pagination; | |||
import org.apache.fop.fo.*; | |||
import org.apache.fop.apps.FOPException; | |||
public class RepeatablePageMasterReference extends PageMasterReference | |||
public class RepeatablePageMasterReference extends FObj | |||
implements SubSequenceSpecifier { | |||
public static class Maker extends FObj.Maker { | |||
@@ -72,11 +72,10 @@ public class RepeatablePageMasterReference extends PageMasterReference | |||
private int maximumRepeats; | |||
private int numberConsumed = 0; | |||
private int BOUNDED = 1; | |||
private int UNBOUNDED = 0; | |||
private int state; | |||
private int boundedness; | |||
public RepeatablePageMasterReference(FObj parent, PropertyList propertyList) | |||
throws FOPException { | |||
@@ -94,7 +93,7 @@ public class RepeatablePageMasterReference extends PageMasterReference | |||
} | |||
} else { | |||
throw new FOPException("fo:repeatable-page-master-reference must be" + | |||
"child of fo:page-sequence, not " | |||
"child of fo:page-sequence-master, not " | |||
+ parent.getName()); | |||
} | |||
@@ -103,23 +102,24 @@ public class RepeatablePageMasterReference extends PageMasterReference | |||
{ | |||
try { | |||
setMaximumRepeats( Integer.parseInt( mr ) ); | |||
this.state = BOUNDED; | |||
this.boundedness = BOUNDED; | |||
} catch (NumberFormatException nfe) { | |||
throw new FOPException( "Invalid number for " + | |||
"'maximum-repeats' property" ); | |||
} | |||
} else { | |||
this.state = UNBOUNDED; // unbounded | |||
this.boundedness = UNBOUNDED; // unbounded | |||
} | |||
} | |||
public String getNextPageMaster( int currentPageNumber, | |||
boolean thisIsFirstPage ) { | |||
boolean thisIsFirstPage, boolean isEmptyPage ) { | |||
String pm = getMasterName(); | |||
if (this.state == BOUNDED) | |||
if (this.boundedness == BOUNDED) | |||
{ | |||
if (numberConsumed < getMaximumRepeats()) { | |||
numberConsumed++; | |||
@@ -127,6 +127,11 @@ public class RepeatablePageMasterReference extends PageMasterReference | |||
pm = null; | |||
} | |||
} | |||
// is flow OK? | |||
if ((pm != null) && this.pageSequenceMaster.isFlowForMasterNameDone( pm )) | |||
pm = null; | |||
return pm; | |||
} | |||
@@ -141,4 +146,18 @@ public class RepeatablePageMasterReference extends PageMasterReference | |||
return this.maximumRepeats; | |||
} | |||
public void setMasterName( String masterName ) | |||
{ | |||
this.masterName = masterName; | |||
} | |||
public String getMasterName() | |||
{ | |||
return masterName; | |||
} | |||
public void reset() | |||
{ | |||
numberConsumed = 0; | |||
} | |||
} |
@@ -76,7 +76,8 @@ public class Root extends FObj { | |||
LayoutMasterSet layoutMasterSet; | |||
Vector pageSequences; | |||
PageSequence currentPageSequence; | |||
protected Root(FObj parent, PropertyList propertyList) throws FOPException | |||
{ | |||
super(parent, propertyList); | |||
@@ -113,13 +114,19 @@ public class Root extends FObj { | |||
Enumeration e = pageSequences.elements(); | |||
while (e.hasMoreElements()) | |||
{ | |||
((PageSequence) e.nextElement()).format(areaTree); | |||
currentPageSequence = (PageSequence) e.nextElement(); | |||
currentPageSequence.format(areaTree); | |||
} | |||
} | |||
public void setLayoutMasterSet(LayoutMasterSet layoutMasterSet) { | |||
this.layoutMasterSet = layoutMasterSet; | |||
this.layoutMasterSet = layoutMasterSet; | |||
} | |||
public PageSequence getCurrentPageSequence() | |||
{ | |||
return currentPageSequence; | |||
} | |||
} |
@@ -121,12 +121,15 @@ public class SimplePageMaster extends FObj { | |||
int contentRectangleHeight = pageHeight - marginTop - marginBottom; | |||
this.pageMaster = new PageMaster(pageWidth, pageHeight); | |||
this.pageMaster.addBody(this.regionBody.makeRegion(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight)); | |||
this.pageMaster.addBody(this.regionBody.makeRegion(contentRectangleXPosition, | |||
contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight)); | |||
if (this.regionBefore != null) | |||
this.pageMaster.addBefore(this.regionBefore.makeRegion(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight)); | |||
this.pageMaster.addBefore(this.regionBefore.makeRegion(contentRectangleXPosition, | |||
contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight)); | |||
if (this.regionAfter != null) | |||
this.pageMaster.addAfter(this.regionAfter.makeRegion(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight)); | |||
this.pageMaster.addAfter(this.regionAfter.makeRegion(contentRectangleXPosition, | |||
contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight)); | |||
} | |||
public PageMaster getPageMaster() { |
@@ -54,7 +54,7 @@ import org.apache.fop.fo.*; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.messaging.MessageHandler; | |||
public class SinglePageMasterReference extends PageMasterReference | |||
public class SinglePageMasterReference extends FObj | |||
implements SubSequenceSpecifier { | |||
public static class Maker extends FObj.Maker { | |||
@@ -101,8 +101,15 @@ public class SinglePageMasterReference extends PageMasterReference | |||
this.state = FIRST; | |||
} | |||
public String getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage ) { | |||
return getMasterName(); | |||
public String getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage, | |||
boolean isEmptyPage) { | |||
if (this.state == FIRST) | |||
{ | |||
this.state = DONE; | |||
return getMasterName(); | |||
} | |||
else | |||
return null; | |||
} | |||
public void setMasterName( String masterName ) | |||
@@ -114,4 +121,10 @@ public class SinglePageMasterReference extends PageMasterReference | |||
{ | |||
return this.masterName; | |||
} | |||
public void reset() | |||
{ | |||
this.state = FIRST; | |||
} | |||
} |
@@ -56,6 +56,8 @@ package org.apache.fop.fo.pagination; | |||
public interface SubSequenceSpecifier | |||
{ | |||
public String getNextPageMaster( int currentPageNumber, | |||
boolean thisIsFirstPage ); | |||
boolean thisIsFirstPage, boolean isEmptyPage ); | |||
public void reset(); | |||
} | |||