aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfotis <fotis@unknown>2000-11-15 10:26:24 +0000
committerfotis <fotis@unknown>2000-11-15 10:26:24 +0000
commiteb0e581ad71052c6afa1afdba6b576f2b9414a65 (patch)
tree6efd52bfe8aa12055e1a6fccb3b907f83e8eef27
parentd03ee13a49a09d14710c8d00cf861062cfc5fc86 (diff)
downloadxmlgraphics-fop-eb0e581ad71052c6afa1afdba6b576f2b9414a65.tar.gz
xmlgraphics-fop-eb0e581ad71052c6afa1afdba6b576f2b9414a65.zip
region-name support, refactoring of region, PageSequence, PageMasterReference, flow/static [Kelly Campbell, Arved Sandstrom]
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193805 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/org/apache/fop/apps/CommandLine.java146
-rw-r--r--src/org/apache/fop/apps/Driver.java49
-rw-r--r--src/org/apache/fop/fo/PropertyListBuilder.java6
-rw-r--r--src/org/apache/fop/fo/flow/Flow.java74
-rw-r--r--src/org/apache/fop/fo/flow/StaticContent.java67
-rw-r--r--src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java112
-rw-r--r--src/org/apache/fop/fo/pagination/LayoutMasterSet.java78
-rw-r--r--src/org/apache/fop/fo/pagination/PageMasterReference.java102
-rw-r--r--src/org/apache/fop/fo/pagination/PageSequence.java456
-rw-r--r--src/org/apache/fop/fo/pagination/PageSequenceMaster.java49
-rw-r--r--src/org/apache/fop/fo/pagination/Region.java161
-rw-r--r--src/org/apache/fop/fo/pagination/RegionAfter.java47
-rw-r--r--src/org/apache/fop/fo/pagination/RegionBefore.java42
-rw-r--r--src/org/apache/fop/fo/pagination/RegionBody.java49
-rw-r--r--src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java67
-rw-r--r--src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java79
-rw-r--r--src/org/apache/fop/fo/pagination/SimplePageMaster.java74
-rw-r--r--src/org/apache/fop/fo/pagination/SinglePageMasterReference.java59
-rw-r--r--src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java8
-rw-r--r--src/org/apache/fop/layout/PageMaster.java20
-rw-r--r--src/org/apache/fop/layout/RegionArea.java (renamed from src/org/apache/fop/layout/Region.java)4
-rw-r--r--src/org/apache/fop/render/pdf/PDFRenderer.java4
22 files changed, 1293 insertions, 460 deletions
diff --git a/src/org/apache/fop/apps/CommandLine.java b/src/org/apache/fop/apps/CommandLine.java
index 3f3711d14..11cf71d33 100644
--- a/src/org/apache/fop/apps/CommandLine.java
+++ b/src/org/apache/fop/apps/CommandLine.java
@@ -80,6 +80,94 @@ import org.apache.fop.messaging.MessageHandler;
*/
public class CommandLine {
+ private String foFile = null;
+ private String pdfFile = null;
+
+ /** show a full dump on error */
+ private static boolean errorDump = false;
+
+ public CommandLine(String[] args)
+ {
+ for (int i=0; i<args.length; i++) {
+ if (args[i].equals("-d") || args[i].equals("--full-error-dump")) {
+ errorDump = true;
+ }
+ else if (args[i].charAt(0) == '-') {
+ printUsage(args[i]);
+ }
+ else if (foFile == null) {
+ foFile = args[i];
+ }
+ else if (pdfFile == null) {
+ pdfFile = args[i];
+ }
+ else {
+ printUsage(args[i]);
+ }
+ }
+ if (foFile == null || pdfFile == null) {
+ printUsage(null);
+ }
+ }
+
+ public void printUsage(String arg)
+ {
+ if (arg != null) {
+ MessageHandler.errorln("Unkown argument: '"+arg+"'");
+ MessageHandler.errorln("Usage: java [-d]"
+ + "org.apache.fop.apps.CommandLine "
+ + "formatting-object-file pdf-file");
+ MessageHandler.errorln("Options:\n"
+ + " -d or --full-error-dump Show stack traces upon error");
+
+ System.exit(1);
+ }
+ }
+
+
+ public void run() {
+
+ XMLReader parser = createParser();
+
+ if (parser == null) {
+ MessageHandler.errorln("ERROR: Unable to create SAX parser");
+ System.exit(1);
+ }
+
+ // setting the parser features
+ try {
+ parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+ } catch (SAXException e) {
+ MessageHandler.errorln("Error in setting up parser feature namespace-prefixes");
+ MessageHandler.errorln("You need a parser which supports SAX version 2");
+ if (errorDump) {
+ e.printStackTrace();
+ }
+ System.exit(1);
+ }
+
+ try {
+ Driver driver = new Driver();
+ driver.setErrorDump(errorDump);
+ driver.setRenderer("org.apache.fop.render.pdf.PDFRenderer", Version.getVersion());
+ driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
+ driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
+ driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
+ driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
+ driver.buildFOTree(parser, fileInputSource(foFile));
+ driver.format();
+ driver.setWriter(new PrintWriter(new FileWriter(pdfFile)));
+ driver.render();
+ } catch (Exception e) {
+ MessageHandler.errorln("FATAL ERROR: " + e.getMessage());
+ if (errorDump){
+ e.printStackTrace();
+ }
+ System.exit(1);
+ }
+ }
+
+
/**
* creates a SAX parser, using the value of org.xml.sax.parser
* defaulting to org.apache.xerces.parsers.SAXParser
@@ -99,13 +187,25 @@ public class CommandLine {
Class.forName(parserClassName).newInstance();
} catch (ClassNotFoundException e) {
org.apache.fop.messaging.MessageHandler.errorln("Could not find " + parserClassName);
+ if (errorDump){
+ e.printStackTrace();
+ }
} catch (InstantiationException e) {
org.apache.fop.messaging.MessageHandler.errorln("Could not instantiate "
+ parserClassName);
+ if (errorDump){
+ e.printStackTrace();
+ }
} catch (IllegalAccessException e) {
org.apache.fop.messaging.MessageHandler.errorln("Could not access " + parserClassName);
+ if (errorDump){
+ e.printStackTrace();
+ }
} catch (ClassCastException e) {
org.apache.fop.messaging.MessageHandler.errorln(parserClassName + " is not a SAX driver");
+ if (errorDump){
+ e.printStackTrace();
+ }
}
return null;
}
@@ -145,47 +245,11 @@ public class CommandLine {
*/
public static void main(String[] args) {
String version = Version.getVersion();
- MessageHandler.errorln(version);
-
-
-
- if (args.length != 2) {
- MessageHandler.errorln("usage: java "
- + "org.apache.fop.apps.CommandLine "
- + "formatting-object-file pdf-file");
- System.exit(1);
- }
-
- XMLReader parser = createParser();
-
- if (parser == null) {
- MessageHandler.errorln("ERROR: Unable to create SAX parser");
- System.exit(1);
- }
+ MessageHandler.errorln(version);
+
+ CommandLine cmdLine = new CommandLine(args);
+ cmdLine.run();
- // setting the parser features
- try {
- parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
- } catch (SAXException e) {
- MessageHandler.errorln("Error in setting up parser feature namespace-prefixes");
- MessageHandler.errorln("You need a parser which supports SAX version 2");
- System.exit(1);
- }
-
- try {
- Driver driver = new Driver();
- driver.setRenderer("org.apache.fop.render.pdf.PDFRenderer", version);
- driver.addElementMapping("org.apache.fop.fo.StandardElementMapping");
- driver.addElementMapping("org.apache.fop.svg.SVGElementMapping");
- driver.addPropertyList("org.apache.fop.fo.StandardPropertyListMapping");
- driver.addPropertyList("org.apache.fop.svg.SVGPropertyListMapping");
- driver.setWriter(new PrintWriter(new FileWriter(args[1])));
- driver.buildFOTree(parser, fileInputSource(args[0]));
- driver.format();
- driver.render();
- } catch (Exception e) {
- MessageHandler.errorln("FATAL ERROR: " + e.getMessage());
- System.exit(1);
- }
}
+
}
diff --git a/src/org/apache/fop/apps/Driver.java b/src/org/apache/fop/apps/Driver.java
index d48b64306..ff2ad79bc 100644
--- a/src/org/apache/fop/apps/Driver.java
+++ b/src/org/apache/fop/apps/Driver.java
@@ -129,11 +129,22 @@ public class Driver {
/** the PrintWriter to use to output the results of the renderer */
protected PrintWriter writer;
+ /** If true, full error stacks are reported */
+ protected boolean errorDump;
+
/** create a new Driver */
public Driver() {
this.treeBuilder = new FOTreeBuilder();
}
+ /** Set the error dump option
+ * @param dump if true, full stacks will be reported to the error log
+ */
+ public void setErrorDump(boolean dump)
+ {
+ errorDump = dump;
+ }
+
/** set the Renderer to use */
public void setRenderer(Renderer renderer) {
this.renderer = renderer;
@@ -199,13 +210,17 @@ public class Driver {
Class.forName(mappingClassName).newInstance();
} catch (ClassNotFoundException e) {
MessageHandler.errorln("Could not find " + mappingClassName);
+ dumpError(e);
} catch (InstantiationException e) {
MessageHandler.errorln("Could not instantiate "
+ mappingClassName);
+ dumpError(e);
} catch (IllegalAccessException e) {
MessageHandler.errorln("Could not access " + mappingClassName);
+ dumpError(e);
} catch (ClassCastException e) {
MessageHandler.errorln(mappingClassName + " is not an element mapping");
+ dumpError(e);
}
return null;
}
@@ -229,13 +244,17 @@ public class Driver {
Class.forName(listClassName).newInstance();
} catch (ClassNotFoundException e) {
MessageHandler.errorln("Could not find " + listClassName);
+ dumpError(e);
} catch (InstantiationException e) {
MessageHandler.errorln("Could not instantiate "
+ listClassName);
+ dumpError(e);
} catch (IllegalAccessException e) {
MessageHandler.errorln("Could not access " + listClassName);
+ dumpError(e);
} catch (ClassCastException e) {
MessageHandler.errorln(listClassName + " is not an property list");
+ dumpError(e);
}
return null;
}
@@ -262,11 +281,16 @@ public class Driver {
try {
parser.parse(source);
} catch (SAXException e) {
- if (e.getException() instanceof FOPException)
+ if (e.getException() instanceof FOPException) {
+ dumpError(e.getException());
throw (FOPException) e.getException();
- else
+ }
+ else {
+ dumpError(e);
throw new FOPException(e.getMessage());
+ }
} catch (IOException e) {
+ dumpError(e);
throw new FOPException(e.getMessage());
}
}
@@ -356,11 +380,32 @@ public class Driver {
}
}
} catch (SAXException e) {
+ dumpError(e);
throw new FOPException(e.getMessage());
}
}
/**
+ * Dumps an error
+ */
+ public void dumpError(Exception e)
+ {
+ if (errorDump) {
+ if (e instanceof SAXException) {
+ e.printStackTrace();
+ if (((SAXException)e).getException() != null) {
+ ((SAXException)e).getException().printStackTrace();
+ }
+ }
+ else {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+
+ /**
* set the PrintWriter to use to output the result of the Renderer
* (if applicable)
*/
diff --git a/src/org/apache/fop/fo/PropertyListBuilder.java b/src/org/apache/fop/fo/PropertyListBuilder.java
index b625d6720..ddeaba833 100644
--- a/src/org/apache/fop/fo/PropertyListBuilder.java
+++ b/src/org/apache/fop/fo/PropertyListBuilder.java
@@ -183,7 +183,11 @@ public class PropertyListBuilder {
else {
propVal = propertyMaker.make(p,attributes.getValue(i),fo);
}
- p.put(propName,propVal);
+
+ if (propVal != null) {
+ p.put(propName,propVal);
+ }
+
} else {
//MessageHandler.errorln("WARNING: property " + attributeName + " ignored");
}
diff --git a/src/org/apache/fop/fo/flow/Flow.java b/src/org/apache/fop/fo/flow/Flow.java
index 58ddefa9d..70b677979 100644
--- a/src/org/apache/fop/fo/flow/Flow.java
+++ b/src/org/apache/fop/fo/flow/Flow.java
@@ -54,9 +54,10 @@ package org.apache.fop.fo.flow;
// FOP
import org.apache.fop.fo.*;
import org.apache.fop.fo.properties.*;
-import org.apache.fop.fo.pagination.PageSequence;
+import org.apache.fop.fo.pagination.*;
import org.apache.fop.layout.Area;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.messaging.MessageHandler;
// Java
import java.util.Hashtable;
@@ -75,13 +76,22 @@ public class Flow extends FObj {
return new Flow.Maker();
}
- PageSequence pageSequence;
- private Area area; // Area in which we lay out our kids
+ /** PageSequence container */
+ private PageSequence pageSequence;
+
+ /** Area in which we lay out our kids */
+ private Area area;
+
+ /** flow-name attribute */
+ private String _flowName;
+
+ private Status _status = new Status(Status.AREA_FULL_NONE);
+
protected Flow(FObj parent, PropertyList propertyList)
throws FOPException {
super(parent, propertyList);
- this.name = "fo:flow";
+ this.name = getElementName();
if (parent.getName().equals("fo:page-sequence")) {
this.pageSequence = (PageSequence) parent;
@@ -89,11 +99,35 @@ public class Flow extends FObj {
throw new FOPException("flow must be child of "
+ "page-sequence, not "
+ parent.getName());
- }
- pageSequence.setFlow(this);
+ }
+ setFlowName(getProperty("flow-name").getString());
+ pageSequence.addFlow(this);
}
+
+ protected void setFlowName(String name)
+ throws FOPException
+ {
+ if (name == null || name.equals("")) {
+ MessageHandler.errorln("WARNING: A 'flow-name' is required for "+getElementName()+". This constraint will be enforced in future versions of FOP");
+ _flowName = "xsl-region-body";
+ }
+ else {
+ _flowName = name;
+ }
+ }
+
+ public String getFlowName()
+ {
+ return _flowName;
+ }
+
public Status layout(Area area) throws FOPException {
+ return layout(area, null);
+
+ }
+
+ public Status layout(Area area, Region region) throws FOPException {
if (this.marker == START) {
this.marker = 0;
}
@@ -103,23 +137,23 @@ public class Flow extends FObj {
int numChildren = this.children.size();
for (int i = this.marker; i < numChildren; i++) {
FObj fo = (FObj) children.elementAt(i);
- Status status;
- if ((status = fo.layout(area)).isIncomplete()) {
- if ((prevChildMustKeepWithNext) && (status.laidOutNone())) {
+ if ((_status = fo.layout(area)).isIncomplete()) {
+ if ((prevChildMustKeepWithNext) && (_status.laidOutNone())) {
this.marker = i - 1;
FObj prevChild = (FObj) children.elementAt(this.marker);
prevChild.removeAreas();
prevChild.resetMarker();
prevChild.removeID(area.getIDReferences());
- return new Status(Status.AREA_FULL_SOME);
+ _status = new Status(Status.AREA_FULL_SOME);
+ return _status;
// should probably return AREA_FULL_NONE if first
// or perhaps an entirely new status code
} else {
this.marker = i;
- return status;
+ return _status;
}
}
- if (status.getCode() == Status.KEEP_WITH_NEXT) {
+ if (_status.getCode() == Status.KEEP_WITH_NEXT) {
prevChildMustKeepWithNext = true;
}
else {
@@ -127,7 +161,8 @@ public class Flow extends FObj {
}
}
- return new Status(Status.OK);
+ _status = new Status(Status.OK);
+ return _status;
}
/**
@@ -139,4 +174,17 @@ public class Flow extends FObj {
return area.getContentWidth(); //getAllocationWidth()??
else return 0; // not laid out yet
}
+
+ protected String getElementName()
+ {
+ return "fo:flow";
+ }
+
+ public Status getStatus()
+ {
+ return _status;
+ }
+
+
+
}
diff --git a/src/org/apache/fop/fo/flow/StaticContent.java b/src/org/apache/fop/fo/flow/StaticContent.java
index 9394c21d7..f9ea28ecc 100644
--- a/src/org/apache/fop/fo/flow/StaticContent.java
+++ b/src/org/apache/fop/fo/flow/StaticContent.java
@@ -53,14 +53,14 @@ package org.apache.fop.fo.flow;
// FOP
import org.apache.fop.fo.*;
import org.apache.fop.fo.properties.*;
-import org.apache.fop.fo.pagination.PageSequence;
+import org.apache.fop.fo.pagination.*;
import org.apache.fop.layout.Area;
import org.apache.fop.apps.FOPException;
// Java
import java.util.Enumeration;
-public class StaticContent extends FObj {
+public class StaticContent extends Flow {
public static class Maker extends FObj.Maker {
public FObj make(FObj parent, PropertyList propertyList)
@@ -73,37 +73,39 @@ public class StaticContent extends FObj {
return new StaticContent.Maker();
}
- PageSequence pageSequence;
-
protected StaticContent(FObj parent, PropertyList propertyList)
throws FOPException {
super(parent, propertyList);
- this.name = "fo:static-content";
-
- if (parent.getName().equals("fo:page-sequence")) {
- this.pageSequence = (PageSequence) parent;
- } else {
- throw new FOPException("static-content must be child of "
- + "fo:page-sequence, not "
- + parent.getName());
- }
- String flowName = this.properties.get("flow-name").getString();
-
- pageSequence.setStaticContent(flowName, this);
}
public Status layout(Area area) throws FOPException {
+ return layout(area, null);
+ }
+
+
+ public Status layout(Area area, Region region) throws FOPException {
int numChildren = this.children.size();
// Set area absolute height so that link rectangles will be drawn correctly in xsl-before and xsl-after
- String flowName = this.properties.get("flow-name").getString();
- if(flowName.equals("xsl-region-before"))
- {
- area.setAbsoluteHeight(-area.getMaxHeight());
+ String regionClass = "none";
+ if (region != null) {
+ regionClass = region.getRegionClass();
}
- else if(flowName.equals("xsl-region-after"))
- {
- area.setAbsoluteHeight(area.getPage().getBody().getMaxHeight());
+ else {
+ if(getFlowName().equals("xsl-region-before")) {
+ regionClass = RegionBefore.REGION_CLASS;
+ }
+ else if(getFlowName().equals("xsl-region-after")) {
+ regionClass = RegionAfter.REGION_CLASS;
+ }
+
+ }
+
+ if(regionClass.equals(RegionBefore.REGION_CLASS)) {
+ area.setAbsoluteHeight(-area.getMaxHeight());
+ }
+ else if(regionClass.equals(RegionAfter.REGION_CLASS)) {
+ area.setAbsoluteHeight(area.getPage().getBody().getMaxHeight());
}
for (int i = 0; i < numChildren; i++) {
@@ -117,9 +119,26 @@ public class StaticContent extends FObj {
}
return(status);
}
-// fo.layout(area);
}
resetMarker();
return new Status(Status.OK);
}
+
+ protected String getElementName()
+ {
+ return "fo:static-content";
+ }
+
+ // flowname checking is more stringient for static content currently
+ protected void setFlowName(String name)
+ throws FOPException
+ {
+ if (name == null || name.equals("")) {
+ throw new FOPException("A 'flow-name' is required for "+getElementName()+".");
+ }
+ else {
+ super.setFlowName(name);
+ }
+
+ }
}
diff --git a/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java b/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
index 5db191dfe..4f6fafacb 100644
--- a/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
+++ b/src/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
@@ -55,8 +55,8 @@ 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)
@@ -69,41 +69,48 @@ public class ConditionalPageMasterReference
return new ConditionalPageMasterReference.Maker();
}
- private String masterName;
- private RepeatablePageMasterAlternatives repeatablePageMasterAlternatives;
-
- private int pagePosition;
- private int oddOrEven;
- private int blankOrNotBlank;
-
+ private RepeatablePageMasterAlternatives repeatablePageMasterAlternatives;
+
+ private String masterName;
+
+ private int pagePosition;
+ private int oddOrEven;
+ private int blankOrNotBlank;
+
public ConditionalPageMasterReference(FObj parent, PropertyList propertyList)
throws FOPException {
super(parent, propertyList);
- this.name = "fo:conditional-page-master-reference";
- if (parent.getName().equals("fo:repeatable-page-master-alternatives")) {
- this.repeatablePageMasterAlternatives =
- (RepeatablePageMasterAlternatives) parent;
- setMasterName( this.properties.get("master-name").getString() );
- if (getMasterName() == null) {
- System.err.println("WARNING: single-page-master-reference" +
- "does not have a master-name and so is being ignored");
- } else {
- this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this);
- }
-
- setPagePosition( this.properties.get("page-position").getEnum() );
- setOddOrEven( this.properties.get("odd-or-even").getEnum() );
- setBlankOrNotBlank( this.properties.get("blank-or-not-blank").getEnum() );
-
- } else {
- throw new FOPException("fo:conditional-page-master-reference must be child "
- + "of fo:repeatable-page-master-alternatives, not "
- + parent.getName());
+ this.name = getElementName();
+ if (getProperty("master-name") != null) {
+ setMasterName(getProperty("master-name").getString() );
}
+
+ validateParent(parent);
+
+ setPagePosition( this.properties.get("page-position").getEnum() );
+ setOddOrEven( this.properties.get("odd-or-even").getEnum() );
+ setBlankOrNotBlank( this.properties.get("blank-or-not-blank").getEnum() );
+
+
}
- protected boolean isValid( int currentPageNumber, boolean thisIsFirstPage )
+ protected void setMasterName( String masterName )
+ {
+ this.masterName = masterName;
+ }
+
+ /**
+ * Returns the "master-name" attribute of this page master reference
+ */
+ public String getMasterName()
+ {
+ return masterName;
+ }
+
+
+ protected boolean isValid( int currentPageNumber, boolean thisIsFirstPage,
+ boolean isEmptyPage)
{
// page-position
boolean okOnPagePosition = true; // default is 'any'
@@ -137,9 +144,22 @@ public class ConditionalPageMasterReference
okOnOddOrEven = false;
}
- // no check for blankness at the moment
+ // 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);
- return (okOnOddOrEven && okOnPagePosition);
}
protected void setPagePosition( int pagePosition )
@@ -171,4 +191,32 @@ public class ConditionalPageMasterReference
{
return this.blankOrNotBlank;
}
+
+ protected String getElementName()
+ {
+ return "fo:conditional-page-master-reference";
+ }
+
+
+ protected void validateParent(FObj parent)
+ throws FOPException
+ {
+ if (parent.getName().equals("fo:repeatable-page-master-alternatives")) {
+ this.repeatablePageMasterAlternatives =
+ (RepeatablePageMasterAlternatives) parent;
+
+ if (getMasterName() == null) {
+ MessageHandler.errorln("WARNING: single-page-master-reference" +
+ "does not have a master-name and so is being ignored");
+ } else {
+ this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this);
+ }
+ } else {
+ throw new FOPException("fo:conditional-page-master-reference must be child "
+ + "of fo:repeatable-page-master-alternatives, not "
+ + parent.getName());
+ }
+ }
+
+
}
diff --git a/src/org/apache/fop/fo/pagination/LayoutMasterSet.java b/src/org/apache/fop/fo/pagination/LayoutMasterSet.java
index b0f8c32de..89d32c8c5 100644
--- a/src/org/apache/fop/fo/pagination/LayoutMasterSet.java
+++ b/src/org/apache/fop/fo/pagination/LayoutMasterSet.java
@@ -55,10 +55,9 @@ import org.apache.fop.fo.*;
import org.apache.fop.fo.properties.*;
import org.apache.fop.apps.FOPException;
import org.apache.fop.layout.PageMaster;
-import org.apache.fop.apps.FOPException;
// Java
-import java.util.Hashtable;
+import java.util.*;
public class LayoutMasterSet extends FObj {
@@ -74,8 +73,10 @@ public class LayoutMasterSet extends FObj {
}
private Hashtable simplePageMasters;
- private Hashtable pageSequenceMasters;
- private Root root;
+ private Hashtable pageSequenceMasters;
+ private Hashtable allRegions;
+
+ private Root root;
protected LayoutMasterSet(FObj parent, PropertyList propertyList)
throws FOPException {
@@ -93,48 +94,27 @@ public class LayoutMasterSet extends FObj {
new FOPException("fo:layout-master-set must be child of fo:root, not "
+ parent.getName());
}
+ allRegions = new Hashtable();
+
}
- public PageMaster getNextPageMaster( String pageSequenceName,
- int currentPageNumber, boolean thisIsFirstPage )
- throws FOPException
- {
- PageMaster pm = null;
-
- PageSequenceMaster psm = getPageSequenceMaster( pageSequenceName );
- if (null != psm)
- {
- pm = psm.getNextPageMaster( currentPageNumber, thisIsFirstPage );
- } else {
- SimplePageMaster spm = getSimplePageMaster( pageSequenceName );
- if (null == spm)
- {
- throw new FOPException( "'master-name' for 'fo:page-sequence'" +
- "matches no 'simple-page-master' or 'page-sequence-master'" );
- }
- pm = spm.getNextPageMaster();
- }
- return pm;
- }
-
- protected void addSimplePageMaster(
- String masterName, SimplePageMaster simplePageMaster)
+ protected void addSimplePageMaster(SimplePageMaster simplePageMaster)
throws FOPException {
// check against duplication of master-name
- if (existsName(masterName))
+ if (existsName(simplePageMaster.getMasterName()))
throw new FOPException( "'master-name' must be unique" +
"across page-masters and page-sequence-masters" );
- this.simplePageMasters.put(masterName, simplePageMaster);
+ this.simplePageMasters.put(simplePageMaster.getMasterName(), simplePageMaster);
}
protected SimplePageMaster getSimplePageMaster(String masterName) {
- return (SimplePageMaster)this.simplePageMasters.get(masterName);
+ return (SimplePageMaster)this.simplePageMasters.get(masterName);
}
protected void addPageSequenceMaster(
String masterName, PageSequenceMaster pageSequenceMaster)
throws FOPException {
- // check against duplication of master-name
+ // check against duplication of master-name
if (existsName(masterName))
throw new FOPException( "'master-name' must be unique " +
"across page-masters and page-sequence-masters" );
@@ -153,4 +133,38 @@ public class LayoutMasterSet extends FObj {
else
return false;
}
+
+ protected void resetPageMasters()
+ {
+ for (Enumeration e = pageSequenceMasters.elements(); e.hasMoreElements(); )
+ {
+ ((PageSequenceMaster)e.nextElement()).reset();
+ }
+
+ }
+
+ protected void checkRegionNames() throws FOPException
+ {
+ // Section 7.33.15 check to see that if a region-name is a
+ // duplicate, that it maps to the same region-class.
+ for (Enumeration spm = simplePageMasters.elements(); spm.hasMoreElements(); ) {
+ SimplePageMaster simplePageMaster = (SimplePageMaster)spm.nextElement();
+ Hashtable spmRegions = simplePageMaster.getRegions();
+ for (Enumeration e = spmRegions.elements(); e.hasMoreElements(); ) {
+ Region region = (Region)e.nextElement();
+ if (allRegions.containsKey(region.getRegionName())) {
+ String localClass = (String)allRegions.get(region.getRegionName());
+ if (!localClass.equals(region.getRegionClass())) {
+ throw new FOPException("Duplicate region-names must map "
+ + "to the same region-class");
+ }
+ }
+ allRegions.put(region.getRegionName(),region.getRegionClass());
+ }
+ }
+ }
+
+
+
+
}
diff --git a/src/org/apache/fop/fo/pagination/PageMasterReference.java b/src/org/apache/fop/fo/pagination/PageMasterReference.java
index b177f7251..3c88405bc 100644
--- a/src/org/apache/fop/fo/pagination/PageMasterReference.java
+++ b/src/org/apache/fop/fo/pagination/PageMasterReference.java
@@ -55,38 +55,88 @@ import org.apache.fop.fo.properties.*;
import org.apache.fop.apps.FOPException;
import org.apache.fop.messaging.MessageHandler;
-public class PageMasterReference extends FObj implements SubSequenceSpecifier {
-
- public static class Maker extends FObj.Maker {
- public FObj make(FObj parent, PropertyList propertyList)
- throws FOPException {
- return new PageMasterReference(parent,propertyList);
- }
- }
+/**
+ * Base PageMasterReference class. Provides implementation for handling the
+ * master-name attribute and containment within a PageSequenceMaster
+ */
+public abstract class PageMasterReference extends FObj
+ implements SubSequenceSpecifier
+{
- public static FObj.Maker maker() {
- return new PageMasterReference.Maker();
- }
+ private String _masterName;
+ private PageSequenceMaster _pageSequenceMaster;
- private String masterName;
-
public PageMasterReference(FObj parent, PropertyList propertyList)
- throws FOPException {
- super(parent, propertyList);
- }
-
- public void setMasterName( String masterName )
- {
- this.masterName = masterName;
+ throws FOPException
+ {
+ super(parent, propertyList);
+ this.name = getElementName();
+ if (getProperty("master-name") != null) {
+ setMasterName(getProperty("master-name").getString() );
}
+ validateParent(parent);
+ }
+
+ protected void setMasterName( String masterName )
+ {
+ _masterName = masterName;
+ }
+
+ /**
+ * Returns the "master-name" attribute of this page master reference
+ */
public String getMasterName()
- {
- return this.masterName;
- }
+ {
+ return _masterName;
+ }
- public String getNextPageMaster( int currentPageNumber,
- boolean thisIsFirstPage ) {
- return getMasterName();
+ protected void setPageSequenceMaster(PageSequenceMaster pageSequenceMaster)
+ {
+ _pageSequenceMaster = pageSequenceMaster;
+ }
+
+ protected PageSequenceMaster getPageSequenceMaster()
+ {
+ return _pageSequenceMaster;
+ }
+
+ public abstract String getNextPageMaster(int currentPageNumber,
+ boolean thisIsFirstPage, boolean isEmptyPage);
+
+ /**
+ * Gets the formating object name for this object. Subclasses must provide this.
+ *
+ * @return the element name of this reference. e.g. fo:repeatable-page-master-reference
+ */
+ protected abstract String getElementName();
+
+ /**
+ * Checks that the parent is the right element. The default implementation
+ * checks for fo:page-sequence-master
+ */
+ protected void validateParent(FObj parent)
+ throws FOPException
+ {
+ if (parent.getName().equals("fo:page-sequence-master")) {
+ _pageSequenceMaster = (PageSequenceMaster)parent;
+
+ if (getMasterName() == null) {
+ MessageHandler.errorln("WARNING: " + getElementName() +
+ " does not have a master-name and so is being ignored");
+ } else {
+ _pageSequenceMaster.addSubsequenceSpecifier(this);
+ }
+ } else {
+ throw new FOPException(getElementName() + " must be" +
+ "child of fo:page-sequence-master, not "
+ + parent.getName());
}
+ }
+
+ public abstract void reset() ;
+
+
+
+
}
diff --git a/src/org/apache/fop/fo/pagination/PageSequence.java b/src/org/apache/fop/fo/pagination/PageSequence.java
index 70930813d..aac9a1ed9 100644
--- a/src/org/apache/fop/fo/pagination/PageSequence.java
+++ b/src/org/apache/fop/fo/pagination/PageSequence.java
@@ -65,12 +65,18 @@ import org.apache.fop.layout.PageMaster;
import org.apache.fop.apps.FOPException;
// Java
-import java.util.Hashtable;
-import java.util.Vector;
+import java.util.*;
+
+/**
+ * This provides pagination of flows onto pages. Much of the logic for paginating
+ * flows is contained in this class. The main entry point is the format method.
+ */
public class PageSequence extends FObj
{
-
+ //
+ // Factory methods
+ //
public static class Maker extends FObj.Maker
{
public FObj make(FObj parent, PropertyList propertyList)
@@ -83,24 +89,61 @@ public class PageSequence extends FObj
return new PageSequence.Maker();
}
- static final int EXPLICIT = 0;
- static final int AUTO = 1;
- static final int AUTO_EVEN = 2;
- static final int AUTO_ODD = 3;
-
- protected Root root;
- protected Flow flow;
- // protected Title title;
- protected StaticContent staticBefore;
- protected StaticContent staticAfter;
- protected LayoutMasterSet layoutMasterSet;
- protected String masterName;
+ //
+ // intial-page-number types
+ //
+ private static final int EXPLICIT = 0;
+ private static final int AUTO = 1;
+ private static final int AUTO_EVEN = 2;
+ private static final int AUTO_ODD = 3;
+
+ //
+ // associations
+ //
+ /** The parent root object */
+ private Root root;
+
+ /** the set of layout masters (provided by the root object) */
+ private LayoutMasterSet layoutMasterSet;
+
+ // There doesn't seem to be anything in the spec requiring flows
+ // to be in the order given, only that they map to the regions
+ // defined in the page sequence, so all we need is this one hashtable
+ // the set of flows includes StaticContent flows also
+
+ /** Map of flows to their flow name (flow-name, Flow) */
+ private Hashtable _flowMap;
+
+ /** the "master-name" attribute */
+ private String masterName;
- protected Page currentPage;
- protected int currentPageNumber = 0;
- protected static int runningPageNumberCounter = 0; //keeps count of page number from previous PageSequence
- protected int pageNumberType; // specifies page numbering type (auto|auto-even|auto-odd|explicit)
- protected boolean thisIsFirstPage; // used to determine whether to calculate auto, auto-even, auto-odd
+
+ //
+ // state attributes used during layout
+ //
+
+ private Page currentPage;
+
+ private int currentPageNumber = 0;
+
+ /** keeps count of page number from previous PageSequence */
+ private static int runningPageNumberCounter = 0;
+
+ /** specifies page numbering type (auto|auto-even|auto-odd|explicit) */
+ private int pageNumberType;
+
+ /** used to determine whether to calculate auto, auto-even, auto-odd */
+ private boolean thisIsFirstPage;
+
+ /** the current subsequence while formatting a given page sequence */
+ private SubSequenceSpecifier currentSubsequence;
+
+ /** the current index in the subsequence list */
+ private int currentSubsequenceNumber = -1; // starting case is -1 so that first getNext increments to 0
+
+ /** the name of the current page master */
+ private String currentPageMasterName;
+
protected PageSequence(FObj parent, PropertyList propertyList)
throws FOPException {
@@ -121,6 +164,12 @@ public class PageSequence extends FObj
}
layoutMasterSet = root.getLayoutMasterSet();
+
+ // best time to run some checks on LayoutMasterSet
+ layoutMasterSet.checkRegionNames();
+
+ _flowMap = new Hashtable();
+
thisIsFirstPage=true; // we are now on the first page of the page sequence
String ipnValue= this.properties.get("initial-page-number").getString();
@@ -141,7 +190,7 @@ public class PageSequence extends FObj
pageNumberType=EXPLICIT;
try
{
- int pageStart = new Integer(ipnValue).intValue();
+ int pageStart = new Integer(ipnValue).intValue();
this.currentPageNumber = (pageStart > 0) ? pageStart - 1 : 0;
}
catch ( NumberFormatException nfe )
@@ -151,37 +200,40 @@ public class PageSequence extends FObj
}
masterName = this.properties.get("master-name").getString();
- }
-
- protected Page makePage(AreaTree areaTree) throws FOPException {
- // layout this page sequence
-
- // while there is still stuff in the flow, ask the
- // layoutMasterSet for a new page
+
- // page number is 0-indexed
- PageMaster pageMaster =
- this.layoutMasterSet.getNextPageMaster(
- masterName, currentPageNumber, thisIsFirstPage );
+ }
+
+ public void addFlow(Flow flow)
+ throws FOPException
+ {
+ if (_flowMap.containsKey(flow.getFlowName())) {
+ throw new FOPException("flow-names must be unique within an fo:page-sequence");
+ }
+ _flowMap.put(flow.getFlowName(), flow);
- // a legal alternative is to use the last sub-sequence
- // specification. That's not done here.
- if ( pageMaster == null )
- {
- throw new FOPException("page masters exhausted");
- }
- return pageMaster.makePage(areaTree);
}
+
+ /**
+ * Runs the formatting of this page sequence into the given area tree
+ */
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;
@@ -205,24 +257,35 @@ public class PageSequence extends FObj
thisIsFirstPage=false;
}
- currentPage.setNumber(++this.currentPageNumber);
- this.runningPageNumberCounter=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);
- if ( (this.staticBefore != null) &&
- (currentPage.getBefore() != null) )
- {
- AreaContainer beforeArea = currentPage.getBefore();
- beforeArea.setIDReferences(areaTree.getIDReferences());
- this.staticBefore.layout(beforeArea);
- }
- if ( (this.staticAfter != null) &&
- (currentPage.getAfter() != null) )
- {
- AreaContainer afterArea = currentPage.getAfter();
- afterArea.setIDReferences(areaTree.getIDReferences());
- this.staticAfter.layout(afterArea);
- }
+
+ formatStaticContent(areaTree);
+
if ( (status.getCode() == Status.FORCE_PAGE_BREAK_EVEN) &&
((currentPageNumber % 2) == 1) )
{
@@ -235,31 +298,276 @@ public class PageSequence extends FObj
{
AreaContainer bodyArea = currentPage.getBody();
bodyArea.setIDReferences(areaTree.getIDReferences());
- status = this.flow.layout(bodyArea);
+
+ Flow flow = getCurrentFlow(RegionBody.REGION_CLASS);
+
+ if (null == flow) {
+ MessageHandler.errorln("No flow found for region-body "
+ + "in page-master '" + currentPageMasterName + "'");
+ break;
+
+ }
+ else {
+ status = flow.layout(bodyArea);
+ }
+
}
MessageHandler.log("]");
areaTree.addPage(currentPage);
- } while ( status.isIncomplete() );
+ } while ( flowsAreIncomplete() );
+
MessageHandler.errorln("");
}
- public void setFlow(Flow flow) {
- this.flow = flow;
- }
+ /**
+ * Creates a new page area for the given parameters
+ * @param areaTree the area tree the page should be contained in
+ * @param firstAvailPageNumber the page number for this page
+ * @param isFirstPage true when this is the first page in the sequence
+ * @param isEmptyPage true if this page will be empty (e.g. forced even or odd break)
+ * @return a Page layout object based on the page master selected from the params
+ */
+ private 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
+ // layoutMasterSet for a new page
- public void setStaticContent(String name, StaticContent staticContent) {
- if ( name.equals("xsl-region-before") )
- {
- this.staticBefore = staticContent;
- }
- else if ( name.equals("xsl-region-after") )
- {
- this.staticAfter = staticContent;
- }
- else
+ // page number is 0-indexed
+ PageMaster pageMaster = getNextPageMaster(masterName, firstAvailPageNumber,
+ isFirstPage, isEmptyPage );
+
+ // a legal alternative is to use the last sub-sequence
+ // specification which should be handled in getNextSubsequence. That's not done here.
+ if ( pageMaster == null )
{
- MessageHandler.errorln("WARNING: this version of FOP only supports "
- + "static-content in xsl-region-before and xsl-region-after");
+ throw new FOPException("page masters exhausted. Cannot recover.");
}
+ return pageMaster.makePage(areaTree);
+ }
+
+ /**
+ * Formats the static content of the current page
+ */
+ private void formatStaticContent(AreaTree areaTree)
+ throws FOPException
+ {
+ SimplePageMaster simpleMaster = getCurrentSimplePageMaster();
+
+ if (simpleMaster.getRegion(RegionBefore.REGION_CLASS) != null && (currentPage.getBefore() != null)) {
+ Flow staticFlow = (Flow)_flowMap.get(simpleMaster.getRegion(RegionBefore.REGION_CLASS).getRegionName());
+ if (staticFlow != null) {
+ AreaContainer beforeArea = currentPage.getBefore();
+ beforeArea.setIDReferences(areaTree.getIDReferences());
+ layoutStaticContent(staticFlow, simpleMaster.getRegion(RegionBefore.REGION_CLASS),
+ beforeArea);
+ }
+ }
+
+ if (simpleMaster.getRegion(RegionAfter.REGION_CLASS) != null && (currentPage.getAfter() != null)) {
+ Flow staticFlow = (Flow)_flowMap.get(simpleMaster.getRegion(RegionAfter.REGION_CLASS).getRegionName());
+ if (staticFlow != null) {
+ AreaContainer afterArea = currentPage.getAfter();
+ afterArea.setIDReferences(areaTree.getIDReferences());
+ layoutStaticContent(staticFlow, simpleMaster.getRegion(RegionAfter.REGION_CLASS),
+ afterArea);
+ }
+
+ }
+
+ }
+
+ private void layoutStaticContent(Flow flow, Region region,
+ AreaContainer area)
+ throws FOPException
+ {
+ if (flow instanceof StaticContent) {
+ AreaContainer beforeArea = currentPage.getBefore();
+ ((StaticContent)flow).layout(area, region);
+ }
+ else {
+ MessageHandler.errorln("WARNING: "+region.getName()+" only supports static-content flows currently. Cannot use flow named '"+flow.getFlowName()+"'");
+ }
+ }
+
+
+
+
+
+ /**
+ * Returns the next SubSequenceSpecifier for the given page sequence master. The result
+ * is bassed on the current state of this page sequence.
+ */
+ // refactored from PageSequenceMaster
+ private SubSequenceSpecifier getNextSubsequence(PageSequenceMaster master)
+ {
+ if (master.getSubSequenceSpecifierCount() > currentSubsequenceNumber + 1) {
+
+ currentSubsequence = master.getSubSequenceSpecifier(currentSubsequenceNumber + 1);
+ currentSubsequenceNumber++;
+ return currentSubsequence;
+ }
+ else {
+ return null;
+ }
+
+ }
+
+ /**
+ * Returns the next simple page master for the given sequence master, page number and
+ * other state information
+ */
+ private SimplePageMaster getNextSimplePageMaster(PageSequenceMaster sequenceMaster,
+ int currentPageNumber,
+ boolean thisIsFirstPage,
+ boolean isEmptyPage)
+ {
+ String nextPageMaster = getNextPageMasterName(sequenceMaster, currentPageNumber, thisIsFirstPage, isEmptyPage);
+ return this.layoutMasterSet.getSimplePageMaster( nextPageMaster );
+
+ }
+
+ private String getNextPageMasterName(PageSequenceMaster sequenceMaster,
+ int currentPageNumber,
+ boolean thisIsFirstPage,
+ boolean isEmptyPage)
+ {
+
+ if (null == currentSubsequence) {
+ currentSubsequence = getNextSubsequence(sequenceMaster);
+ }
+
+ String nextPageMaster =
+ currentSubsequence.getNextPageMaster( currentPageNumber, thisIsFirstPage, isEmptyPage );
+
+
+ if (null == nextPageMaster || isFlowForMasterNameDone(currentPageMasterName)) {
+ SubSequenceSpecifier nextSubsequence = getNextSubsequence(sequenceMaster);
+ if (nextSubsequence == null) {
+ MessageHandler.errorln("\nWARNING: Page subsequences exhausted. Using previous subsequence.");
+ thisIsFirstPage = true; // this becomes the first page in the new (old really) page master
+ currentSubsequence.reset();
+
+ // we leave currentSubsequence alone
+ }
+ else {
+ currentSubsequence = nextSubsequence;
+ }
+
+ nextPageMaster = currentSubsequence.getNextPageMaster( currentPageNumber,
+ thisIsFirstPage,
+ isEmptyPage);
+ }
+ currentPageMasterName = nextPageMaster;
+
+ return nextPageMaster;
+
+ }
+
+ private SimplePageMaster getCurrentSimplePageMaster()
+ {
+ return this.layoutMasterSet.getSimplePageMaster( currentPageMasterName );
+ }
+
+ private String getCurrentPageMasterName()
+ {
+ return currentPageMasterName;
+ }
+
+ // refactored from LayoutMasterSet
+ private PageMaster getNextPageMaster(String pageSequenceName,
+ int currentPageNumber,
+ boolean thisIsFirstPage,
+ boolean isEmptyPage )
+ throws FOPException
+ {
+ PageMaster pageMaster = null;
+
+ // see if there is a page master sequence for this master name
+ PageSequenceMaster sequenceMaster =
+ this.layoutMasterSet.getPageSequenceMaster( pageSequenceName );
+
+ if (sequenceMaster != null) {
+ pageMaster = getNextSimplePageMaster(sequenceMaster,
+ currentPageNumber,
+ thisIsFirstPage,
+ isEmptyPage).getPageMaster();
+
+ } else { // otherwise see if there's a simple master by the given name
+ SimplePageMaster simpleMaster =
+ this.layoutMasterSet.getSimplePageMaster( pageSequenceName );
+ if (simpleMaster == null) {
+ throw new FOPException( "'master-name' for 'fo:page-sequence'" +
+ "matches no 'simple-page-master' or 'page-sequence-master'" );
+ }
+ currentPageMasterName = pageSequenceName;
+
+ pageMaster = simpleMaster.getNextPageMaster();
+ }
+ return pageMaster;
+ }
+
+
+ /**
+ * Returns true when there is more flow elements left to lay out.
+ */
+ private boolean flowsAreIncomplete()
+ {
+ boolean isIncomplete = false;
+
+ for (Enumeration e = _flowMap.elements(); e.hasMoreElements(); ) {
+ Flow flow = (Flow)e.nextElement();
+ if (flow instanceof StaticContent) {
+ continue;
+ }
+
+ Status status = flow.getStatus();
+ isIncomplete |= status.isIncomplete();
+ }
+ return isIncomplete;
+ }
+
+ /**
+ * Returns the flow that maps to the given region class for the current
+ * page master.
+ */
+ private Flow getCurrentFlow(String regionClass)
+ {
+ Region region = getCurrentSimplePageMaster().getRegion(regionClass);
+ if (region != null) {
+ Flow flow = (Flow)_flowMap.get(region.getRegionName());
+ return flow;
+
+ }
+ else {
+
+ System.out.println("flow is null. regionClass = '"+regionClass+"' currentSPM = "+getCurrentSimplePageMaster());
+
+ return null;
+ }
+
+ }
+
+ private 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 (masterName != null) {
+
+ SimplePageMaster spm = this.layoutMasterSet.getSimplePageMaster( masterName );
+ Region region = spm.getRegion(RegionBody.REGION_CLASS);
+
+
+ Flow flow = (Flow)_flowMap.get( region.getRegionName() );
+ if ((null == flow) || flow.getStatus().isIncomplete())
+ return false;
+ else
+ return true;
+ }
+ return false;
+
}
+
}
diff --git a/src/org/apache/fop/fo/pagination/PageSequenceMaster.java b/src/org/apache/fop/fo/pagination/PageSequenceMaster.java
index 068e71bc7..182805ca7 100644
--- a/src/org/apache/fop/fo/pagination/PageSequenceMaster.java
+++ b/src/org/apache/fop/fo/pagination/PageSequenceMaster.java
@@ -54,12 +54,11 @@ package org.apache.fop.fo.pagination;
import org.apache.fop.fo.*;
import org.apache.fop.fo.properties.*;
import org.apache.fop.layout.PageMaster;
-import org.apache.fop.layout.Region;
import org.apache.fop.apps.FOPException;
import org.apache.fop.messaging.MessageHandler;
// Java
-import java.util.Vector;
+import java.util.*;
public class PageSequenceMaster extends FObj {
@@ -76,7 +75,7 @@ public class PageSequenceMaster extends FObj {
LayoutMasterSet layoutMasterSet;
Vector subSequenceSpecifiers;
- SubSequenceSpecifier currentPmr;
+
// The terminology may be confusing. A 'page-sequence-master' consists
// of a sequence of what the XSL spec refers to as
@@ -95,7 +94,7 @@ public class PageSequenceMaster extends FObj {
this.layoutMasterSet = (LayoutMasterSet) parent;
String pm = this.properties.get("master-name").getString();
if (pm == null) {
- System.err.println("WARNING: page-sequence-master does not have "
+ MessageHandler.errorln("WARNING: page-sequence-master does not have "
+ "a page-master-name and so is being ignored");
} else {
this.layoutMasterSet.addPageSequenceMaster(pm, this);
@@ -109,33 +108,31 @@ public class PageSequenceMaster extends FObj {
protected void addSubsequenceSpecifier( SubSequenceSpecifier pageMasterReference )
{
- subSequenceSpecifiers.addElement( pageMasterReference );
+ subSequenceSpecifiers.addElement( pageMasterReference );
}
- protected SubSequenceSpecifier getNextSubsequenceSpecifier()
+ protected SubSequenceSpecifier getSubSequenceSpecifier(int sequenceNumber)
{
- currentPmr = (SubSequenceSpecifier)subSequenceSpecifiers.elementAt( 0 );
- subSequenceSpecifiers.removeElementAt(0);
- return currentPmr;
+ if (sequenceNumber >=0 && sequenceNumber < getSubSequenceSpecifierCount()) {
+ return (SubSequenceSpecifier)subSequenceSpecifiers.elementAt(sequenceNumber);
+ }
+ return null;
+
+
}
-
- public PageMaster getNextPageMaster( int currentPageNumber, boolean thisIsFirstPage )
+
+ protected int getSubSequenceSpecifierCount()
{
- if (null == currentPmr)
- {
- currentPmr = getNextSubsequenceSpecifier();
- }
-
- String nextPageMaster =
- currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage );
-
- if (null == nextPageMaster)
- {
- currentPmr = getNextSubsequenceSpecifier();
- nextPageMaster =
- currentPmr.getNextPageMaster( currentPageNumber, thisIsFirstPage );
- }
+ return subSequenceSpecifiers.size();
+ }
+
+ public void reset()
+ {
+ for (Enumeration e = subSequenceSpecifiers.elements(); e.hasMoreElements(); ) {
+ ((SubSequenceSpecifier)e.nextElement()).reset();
+ }
- return this.layoutMasterSet.getSimplePageMaster( nextPageMaster ).getPageMaster();
}
+
+
}
diff --git a/src/org/apache/fop/fo/pagination/Region.java b/src/org/apache/fop/fo/pagination/Region.java
new file mode 100644
index 000000000..8893fae8c
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/Region.java
@@ -0,0 +1,161 @@
+/*-- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fo.pagination;
+
+// FOP
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.layout.RegionArea;
+
+/**
+ * This is an abstract base class for pagination regions
+ */
+public abstract class Region extends FObj
+{
+ public static final String PROP_REGION_NAME = "region-name";
+
+ private SimplePageMaster _layoutMaster;
+ private String _regionName;
+
+ protected Region(FObj parent, PropertyList propertyList)
+ throws FOPException
+ {
+ super(parent, propertyList);
+ this.name = getElementName();
+
+ // regions may have name, or default
+ if (null == this.properties.get(PROP_REGION_NAME)) {
+ setRegionName(getDefaultRegionName());
+ }
+ else if (this.properties.get(PROP_REGION_NAME).getString().equals("")) {
+ setRegionName(getDefaultRegionName());
+ }
+ else {
+ setRegionName(this.properties.get(PROP_REGION_NAME).getString());
+ // check that name is OK. Not very pretty.
+ if (isReserved(getRegionName()) &&
+ !getRegionName().equals(getDefaultRegionName())) {
+ throw new FOPException(PROP_REGION_NAME+" '" + _regionName
+ + "' for "+this.name+" not permitted.");
+ }
+ }
+
+ if (parent.getName().equals("fo:simple-page-master")) {
+ _layoutMaster = (SimplePageMaster) parent;
+ getPageMaster().addRegion(this);
+ } else {
+ throw new FOPException(getElementName()+" must be child "
+ + "of simple-page-master, not "
+ + parent.getName());
+ }
+ }
+
+ /**
+ * Creates a Region layout object for this pagination Region.
+ */
+ abstract RegionArea makeRegionArea(int allocationRectangleXPosition,
+ int allocationRectangleYPosition,
+ int allocationRectangleWidth,
+ int allocationRectangleHeight);
+
+ /**
+ * Returns the default region name (xsl-region-before, xsl-region-start,
+ * etc.)
+ */
+ protected abstract String getDefaultRegionName();
+
+ /**
+ * Returns the element name ("fo:region-body", "fo:region-start",
+ * etc.)
+ */
+ protected abstract String getElementName();
+
+ public abstract String getRegionClass();
+
+
+ /**
+ * Returns the name of this region
+ */
+ public String getRegionName()
+ {
+ return _regionName;
+ }
+
+ private void setRegionName(String name)
+ {
+ _regionName = name;
+ }
+
+ protected SimplePageMaster getPageMaster()
+ {
+ return _layoutMaster;
+ }
+
+
+ /**
+ * Checks to see if a given region name is one of the reserved names
+ *
+ * @param name a region name to check
+ * @return true if the name parameter is a reserved region name
+ */
+ protected boolean isReserved(String name)
+ throws FOPException
+ {
+ return (name.equals( "xsl-region-before" ) ||
+ name.equals( "xsl-region-start" ) ||
+ name.equals( "xsl-region-end" ) ||
+ name.equals( "xsl-region-after" ) ||
+ name.equals( "xsl-before-float-separator" ) ||
+ name.equals( "xsl-footnote-separator" ));
+ }
+
+}
diff --git a/src/org/apache/fop/fo/pagination/RegionAfter.java b/src/org/apache/fop/fo/pagination/RegionAfter.java
index 9b8872e1f..828907549 100644
--- a/src/org/apache/fop/fo/pagination/RegionAfter.java
+++ b/src/org/apache/fop/fo/pagination/RegionAfter.java
@@ -51,12 +51,12 @@
package org.apache.fop.fo.pagination;
// FOP
-import org.apache.fop.fo.*;
-import org.apache.fop.fo.properties.*;
-import org.apache.fop.layout.Region;
-import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.layout.RegionArea;
-public class RegionAfter extends FObj {
+public class RegionAfter extends Region {
public static class Maker extends FObj.Maker {
public FObj make(FObj parent, PropertyList propertyList) throws FOPException {
@@ -68,24 +68,16 @@ public class RegionAfter extends FObj {
return new RegionAfter.Maker();
}
- SimplePageMaster layoutMaster;
+ public static final String REGION_CLASS = "after";
+
protected RegionAfter(FObj parent, PropertyList propertyList)
- throws FOPException {
+ throws FOPException
+ {
super(parent, propertyList);
- this.name = "fo:region-after";
-
- if (parent.getName().equals("fo:simple-page-master")) {
- this.layoutMaster = (SimplePageMaster) parent;
- this.layoutMaster.setRegionAfter(this);
- } else {
- throw new FOPException("region-after must be child "
- + "of simple-page-master, not "
- + parent.getName());
- }
}
- Region makeRegion(int allocationRectangleXPosition,
+ RegionArea makeRegionArea(int allocationRectangleXPosition,
int allocationRectangleYPosition,
int allocationRectangleWidth,
int allocationRectangleHeight) {
@@ -95,10 +87,27 @@ public class RegionAfter extends FObj {
int marginRight = this.properties.get("margin-right").getLength().mvalue();
int extent = this.properties.get("extent").getLength().mvalue();
- return new Region(allocationRectangleXPosition + marginLeft,
+ return new RegionArea(allocationRectangleXPosition + marginLeft,
allocationRectangleYPosition -
allocationRectangleHeight + extent,
allocationRectangleWidth - marginLeft -
marginRight,extent);
}
+
+
+ protected String getDefaultRegionName()
+ {
+ return "xsl-region-after";
+ }
+
+ protected String getElementName()
+ {
+ return "fo:region-after";
+ }
+
+ public String getRegionClass()
+ {
+ return REGION_CLASS;
+ }
+
}
diff --git a/src/org/apache/fop/fo/pagination/RegionBefore.java b/src/org/apache/fop/fo/pagination/RegionBefore.java
index 55747c196..2fcbf0259 100644
--- a/src/org/apache/fop/fo/pagination/RegionBefore.java
+++ b/src/org/apache/fop/fo/pagination/RegionBefore.java
@@ -53,10 +53,10 @@ package org.apache.fop.fo.pagination;
// FOP
import org.apache.fop.fo.*;
import org.apache.fop.fo.properties.*;
-import org.apache.fop.layout.Region;
+import org.apache.fop.layout.RegionArea;
import org.apache.fop.apps.FOPException;
-public class RegionBefore extends FObj {
+public class RegionBefore extends Region {
public static class Maker extends FObj.Maker {
public FObj make(FObj parent, PropertyList propertyList) throws FOPException {
@@ -68,24 +68,17 @@ public class RegionBefore extends FObj {
return new RegionBefore.Maker();
}
- SimplePageMaster layoutMaster;
+ public static final String REGION_CLASS = "before";
+
protected RegionBefore(FObj parent, PropertyList propertyList)
- throws FOPException {
+ throws FOPException
+ {
super(parent, propertyList);
- this.name = "fo:region-before";
-
- if (parent.getName().equals("fo:simple-page-master")) {
- this.layoutMaster = (SimplePageMaster) parent;
- this.layoutMaster.setRegionBefore(this);
- } else {
- throw new FOPException("region-before must be child of "
- + "simple-page-master, not "
- + parent.getName());
- }
}
+
- Region makeRegion(int allocationRectangleXPosition,
+ RegionArea makeRegionArea(int allocationRectangleXPosition,
int allocationRectangleYPosition,
int allocationRectangleWidth,
int allocationRectangleHeight) {
@@ -95,9 +88,26 @@ public class RegionBefore extends FObj {
int marginRight = this.properties.get("margin-right").getLength().mvalue();
int extent = this.properties.get("extent").getLength().mvalue();
- return new Region(allocationRectangleXPosition + marginLeft,
+ return new RegionArea(allocationRectangleXPosition + marginLeft,
allocationRectangleYPosition - marginTop,
allocationRectangleWidth - marginLeft -
marginRight, extent);
}
+
+
+ protected String getDefaultRegionName()
+ {
+ return "xsl-region-before";
+ }
+
+ protected String getElementName()
+ {
+ return "fo:region-before";
+ }
+
+ public String getRegionClass()
+ {
+ return REGION_CLASS;
+ }
+
}
diff --git a/src/org/apache/fop/fo/pagination/RegionBody.java b/src/org/apache/fop/fo/pagination/RegionBody.java
index 72a86819b..b8c6daa42 100644
--- a/src/org/apache/fop/fo/pagination/RegionBody.java
+++ b/src/org/apache/fop/fo/pagination/RegionBody.java
@@ -51,13 +51,14 @@
package org.apache.fop.fo.pagination;
// FOP
-import org.apache.fop.fo.*;
-import org.apache.fop.fo.properties.*;
-import org.apache.fop.layout.Region;
-import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.layout.RegionArea;
-public class RegionBody extends FObj {
-
+public class RegionBody extends Region {
+
+
public static class Maker extends FObj.Maker {
public FObj make(FObj parent, PropertyList propertyList) throws FOPException {
return new RegionBody(parent, propertyList);
@@ -68,21 +69,17 @@ public class RegionBody extends FObj {
return new RegionBody.Maker();
}
+ public static final String REGION_CLASS = "body";
+
+
protected RegionBody(FObj parent, PropertyList propertyList)
- throws FOPException {
+ throws FOPException
+ {
super(parent, propertyList);
- this.name = "fo:region-body";
-
- if (parent.getName().equals("fo:simple-page-master")) {
- ((SimplePageMaster) parent).setRegionBody(this);
- } else {
- throw new FOPException("region-body must be child of "
- + "simple-page-master, not "
- + parent.getName());
- }
}
+
- Region makeRegion(int allocationRectangleXPosition,
+ RegionArea makeRegionArea(int allocationRectangleXPosition,
int allocationRectangleYPosition,
int allocationRectangleWidth,
int allocationRectangleHeight) {
@@ -91,10 +88,26 @@ public class RegionBody extends FObj {
int marginLeft = this.properties.get("margin-left").getLength().mvalue();
int marginRight = this.properties.get("margin-right").getLength().mvalue();
- return new Region(allocationRectangleXPosition + marginLeft,
+ return new RegionArea(allocationRectangleXPosition + marginLeft,
allocationRectangleYPosition - marginTop,
allocationRectangleWidth - marginLeft -
marginRight, allocationRectangleHeight -
marginTop - marginBottom);
}
+
+ protected String getDefaultRegionName()
+ {
+ return "xsl-region-body";
+ }
+
+ protected String getElementName()
+ {
+ return "fo:region-body";
+ }
+
+ public String getRegionClass()
+ {
+ return REGION_CLASS;
+ }
+
}
diff --git a/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java b/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
index 891e91cf3..4701b22e3 100644
--- a/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
+++ b/src/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
@@ -60,6 +60,9 @@ import java.util.Vector;
public class RepeatablePageMasterAlternatives extends FObj
implements SubSequenceSpecifier {
+ private static final int INFINITE = -1;
+
+
public static class Maker extends FObj.Maker {
public FObj make(FObj parent, PropertyList propertyList)
throws FOPException {
@@ -73,13 +76,12 @@ public class RepeatablePageMasterAlternatives extends FObj
private PageSequenceMaster pageSequenceMaster;
+ /**
+ * Max times this page master can be repeated.
+ * INFINITE is used for the unbounded case */
private int maximumRepeats;
private int numberConsumed = 0;
-
- private int BOUNDED = 1;
- private int UNBOUNDED = 0;
-
- private int state;
+
private Vector conditionalPageMasterRefs;
public RepeatablePageMasterAlternatives(FObj parent, PropertyList propertyList)
@@ -98,32 +100,32 @@ public class RepeatablePageMasterAlternatives extends FObj
parent.getName());
}
- String mr = this.properties.get("maximum-repeats").getString();
- if (!mr.equals("no-limit"))
- {
+ String mr = getProperty("maximum-repeats").getString();
+ if (mr.equals("no-limit")) {
+ setMaximumRepeats(INFINITE);
+ }
+ else {
try {
- setMaximumRepeats( Integer.parseInt( mr ) );
- this.state = BOUNDED;
+ setMaximumRepeats( Integer.parseInt( mr ) );
} catch (NumberFormatException nfe) {
- throw new FOPException( "Invalid number for " +
- "'maximum-repeats' property" );
+ throw new FOPException( "Invalid number for " +
+ "'maximum-repeats' property" );
}
-
- } else {
- this.state = 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 (numberConsumed < getMaximumRepeats()) {
- numberConsumed++;
- } else {
- return null;
- }
+ if (getMaximumRepeats() != INFINITE ) {
+ if (numberConsumed < getMaximumRepeats()) {
+ numberConsumed++;
+ } else {
+ return null;
+ }
}
for (int i = 0; i < conditionalPageMasterRefs.size(); i++)
@@ -132,20 +134,25 @@ public class RepeatablePageMasterAlternatives extends FObj
(ConditionalPageMasterReference)conditionalPageMasterRefs.elementAt(i);
// 0-indexed page number
- if (cpmr.isValid(currentPageNumber + 1, thisIsFirstPage))
+ if (cpmr.isValid(currentPageNumber + 1, thisIsFirstPage,false))
{
pm = cpmr.getMasterName();
break;
}
}
-
return pm;
}
private void setMaximumRepeats( int maximumRepeats)
{
+ if (maximumRepeats == INFINITE) {
+ this.maximumRepeats = maximumRepeats;
+ }
+ else {
this.maximumRepeats =
- (maximumRepeats < 0) ? 0 : maximumRepeats;
+ (maximumRepeats < 0) ? 0 : maximumRepeats;
+ }
+
}
private int getMaximumRepeats()
@@ -159,4 +166,14 @@ public class RepeatablePageMasterAlternatives extends FObj
this.conditionalPageMasterRefs.addElement( cpmr );
}
+ public void reset()
+ {
+ this.numberConsumed = 0;
+ }
+
+
+ protected PageSequenceMaster getPageSequenceMaster()
+ {
+ return pageSequenceMaster;
+ }
}
diff --git a/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java b/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
index ac9c32723..098832f66 100644
--- a/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
+++ b/src/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
@@ -56,6 +56,8 @@ import org.apache.fop.apps.FOPException;
public class RepeatablePageMasterReference extends PageMasterReference
implements SubSequenceSpecifier {
+ private static final int INFINITE = -1;
+
public static class Maker extends FObj.Maker {
public FObj make(FObj parent, PropertyList propertyList)
throws FOPException {
@@ -67,73 +69,56 @@ public class RepeatablePageMasterReference extends PageMasterReference
return new RepeatablePageMasterReference.Maker();
}
- private String masterName;
- private PageSequenceMaster pageSequenceMaster;
+
+ private PageSequenceMaster pageSequenceMaster;
private int maximumRepeats;
private int numberConsumed = 0;
- private int BOUNDED = 1;
- private int UNBOUNDED = 0;
-
- private int state;
-
public RepeatablePageMasterReference(FObj parent, PropertyList propertyList)
throws FOPException {
super(parent, propertyList);
- this.name = "fo:repeatable-page-master-reference";
-
- if (parent.getName().equals("fo:page-sequence-master")) {
- this.pageSequenceMaster = (PageSequenceMaster) parent;
- setMasterName( this.properties.get("master-name").getString() );
- if (getMasterName() == null) {
- System.err.println("WARNING: repeatable-page-master-reference" +
- "does not have a master-name and so is being ignored");
- } else {
- this.pageSequenceMaster.addSubsequenceSpecifier(this);
- }
- } else {
- throw new FOPException("fo:repeatable-page-master-reference must be" +
- "child of fo:page-sequence, not "
- + parent.getName());
- }
-
- String mr = this.properties.get("maximum-repeats").getString();
- if (!mr.equals("no-limit"))
+
+ String mr = getProperty("maximum-repeats").getString();
+ if (mr.equals("no-limit"))
{
+ setMaximumRepeats(INFINITE);
+ }
+ else {
try {
- setMaximumRepeats( Integer.parseInt( mr ) );
- this.state = BOUNDED;
+ setMaximumRepeats( Integer.parseInt( mr ) );
} catch (NumberFormatException nfe) {
- throw new FOPException( "Invalid number for " +
- "'maximum-repeats' property" );
+ throw new FOPException( "Invalid number for " +
+ "'maximum-repeats' property" );
}
-
- } else {
- this.state = UNBOUNDED; // unbounded
}
}
public String getNextPageMaster( int currentPageNumber,
- boolean thisIsFirstPage ) {
+ boolean thisIsFirstPage,
+ boolean isEmptyPage ) {
String pm = getMasterName();
- if (this.state == BOUNDED)
- {
- if (numberConsumed < getMaximumRepeats()) {
- numberConsumed++;
- } else {
- pm = null;
- }
+ if (getMaximumRepeats() != INFINITE ) {
+ if (numberConsumed < getMaximumRepeats()) {
+ numberConsumed++;
+ } else {
+ pm = null;
+ }
}
return pm;
}
private void setMaximumRepeats( int maximumRepeats)
{
+ if (maximumRepeats == INFINITE) {
+ this.maximumRepeats = maximumRepeats;
+ }
+ else {
this.maximumRepeats =
- (maximumRepeats < 0) ? 0 : maximumRepeats;
+ (maximumRepeats < 0) ? 0 : maximumRepeats;
+ }
}
private int getMaximumRepeats()
@@ -141,4 +126,14 @@ public class RepeatablePageMasterReference extends PageMasterReference
return this.maximumRepeats;
}
+ protected String getElementName()
+ {
+ return "fo:repeatable-page-master-reference";
+ }
+
+ public void reset()
+ {
+ this.numberConsumed = 0;
+ }
+
}
diff --git a/src/org/apache/fop/fo/pagination/SimplePageMaster.java b/src/org/apache/fop/fo/pagination/SimplePageMaster.java
index 556273354..a4bfeacde 100644
--- a/src/org/apache/fop/fo/pagination/SimplePageMaster.java
+++ b/src/org/apache/fop/fo/pagination/SimplePageMaster.java
@@ -55,9 +55,11 @@ import org.apache.fop.fo.*;
import org.apache.fop.messaging.MessageHandler;
import org.apache.fop.fo.properties.*;
import org.apache.fop.layout.PageMaster;
-import org.apache.fop.layout.Region;
import org.apache.fop.apps.FOPException;
+import java.util.Hashtable;
+
+
public class SimplePageMaster extends FObj {
public static class Maker extends FObj.Maker {
@@ -71,13 +73,14 @@ public class SimplePageMaster extends FObj {
return new SimplePageMaster.Maker();
}
- RegionBody regionBody;
- RegionBefore regionBefore;
- RegionAfter regionAfter;
-
+ /** Page regions (regionClass, Region) */
+ private Hashtable _regions;
+
+
LayoutMasterSet layoutMasterSet;
PageMaster pageMaster;
-
+ String masterName;
+
protected SimplePageMaster(FObj parent, PropertyList propertyList)
throws FOPException {
super(parent, propertyList);
@@ -85,18 +88,20 @@ public class SimplePageMaster extends FObj {
if (parent.getName().equals("fo:layout-master-set")) {
this.layoutMasterSet = (LayoutMasterSet) parent;
- String pm = this.properties.get("master-name").getString();
- if (pm == null) {
+ masterName = this.properties.get("master-name").getString();
+ if (masterName == null) {
MessageHandler.errorln("WARNING: simple-page-master does not have "
+ "a master-name and so is being ignored");
} else {
- this.layoutMasterSet.addSimplePageMaster(pm, this);
+ this.layoutMasterSet.addSimplePageMaster(this);
}
} else {
throw new FOPException("fo:simple-page-master must be child "
+ "of fo:layout-master-set, not "
+ parent.getName());
}
+ _regions = new Hashtable();
+
}
protected void end() {
@@ -114,12 +119,21 @@ 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));
-
- if (this.regionBefore != null)
- this.pageMaster.addBefore(this.regionBefore.makeRegion(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight));
- if (this.regionAfter != null)
- this.pageMaster.addAfter(this.regionAfter.makeRegion(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight));
+ if (getRegion(RegionBody.REGION_CLASS) != null) {
+ this.pageMaster.addBody(getRegion(RegionBody.REGION_CLASS).makeRegionArea(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight));
+ }
+ else {
+ MessageHandler.errorln("ERROR: simple-page-master must have a region of class "+RegionBody.REGION_CLASS);
+ }
+
+ if (getRegion(RegionBefore.REGION_CLASS) != null) {
+ this.pageMaster.addBefore(getRegion(RegionBefore.REGION_CLASS).makeRegionArea(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight));
+ }
+
+ if (getRegion(RegionAfter.REGION_CLASS) != null) {
+ this.pageMaster.addAfter(getRegion(RegionAfter.REGION_CLASS).makeRegionArea(contentRectangleXPosition,contentRectangleYPosition,contentRectangleWidth,contentRectangleHeight));
+ }
+
}
public PageMaster getPageMaster() {
@@ -130,15 +144,33 @@ public class SimplePageMaster extends FObj {
return this.pageMaster;
}
- protected void setRegionAfter(RegionAfter region) {
- this.regionAfter = region;
+ public String getMasterName()
+ {
+ return masterName;
}
+
- protected void setRegionBefore(RegionBefore region) {
- this.regionBefore = region;
+ protected void addRegion(Region region)
+ throws FOPException
+ {
+ if (_regions.containsKey(region.getRegionClass())) {
+ throw new FOPException("Only one region of class "+region.getRegionClass()+" allowed within a simple-page-master.");
+ }
+ else {
+ _regions.put(region.getRegionClass(), region);
+ }
+ }
+
+ protected Region getRegion(String regionClass)
+ {
+ return (Region)_regions.get(regionClass);
}
- protected void setRegionBody(RegionBody region) {
- this.regionBody = region;
+ protected Hashtable getRegions()
+ {
+ return _regions;
}
+
+
+
}
diff --git a/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java b/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java
index cf6071c4e..5f05b0d70 100644
--- a/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java
+++ b/src/org/apache/fop/fo/pagination/SinglePageMasterReference.java
@@ -67,51 +67,42 @@ public class SinglePageMasterReference extends PageMasterReference
public static FObj.Maker maker() {
return new SinglePageMasterReference.Maker();
}
-
- private String masterName;
- private PageSequenceMaster pageSequenceMaster;
-
+
private static final int FIRST = 0;
private static final int DONE = 1;
private int state;
-
+
public SinglePageMasterReference(FObj parent, PropertyList propertyList)
throws FOPException {
-
super(parent, propertyList);
- this.name = "fo:single-page-master-reference";
-
- if (parent.getName().equals("fo:page-sequence-master")) {
- this.pageSequenceMaster = (PageSequenceMaster) parent;
- setMasterName( this.properties.get("master-name").getString() );
-
- if (getMasterName() == null) {
- MessageHandler.error("WARNING: single-page-master-reference" +
- "does not have a master-name and so is being ignored");
- } else {
- this.pageSequenceMaster.addSubsequenceSpecifier(this);
- }
- } else {
- throw new FOPException("fo:page-sequence-master must be child "
- + "of fo:layout-master-set, not "
- + parent.getName());
- }
-
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 )
- {
- this.masterName = masterName;
- }
+ public void reset()
+ {
+ this.state = FIRST;
+ }
+
- public String getMasterName()
- {
- return this.masterName;
- }
+ protected String getElementName()
+ {
+ return "fo:single-page-master-reference";
+ }
+
+
}
diff --git a/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java b/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java
index fe18f15fb..0e4828bc0 100644
--- a/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java
+++ b/src/org/apache/fop/fo/pagination/SubSequenceSpecifier.java
@@ -56,6 +56,12 @@ package org.apache.fop.fo.pagination;
public interface SubSequenceSpecifier
{
public String getNextPageMaster( int currentPageNumber,
- boolean thisIsFirstPage );
+ boolean thisIsFirstPage, boolean isEmptyPage);
+ /**
+ * Called before a new page sequence is rendered so subsequences can reset
+ * any state they keep during the formatting process.
+ */
+ public void reset();
+
}
diff --git a/src/org/apache/fop/layout/PageMaster.java b/src/org/apache/fop/layout/PageMaster.java
index a677ad4ff..f564abda3 100644
--- a/src/org/apache/fop/layout/PageMaster.java
+++ b/src/org/apache/fop/layout/PageMaster.java
@@ -55,34 +55,34 @@ public class PageMaster {
private int width;
private int height;
- private Region body;
- private Region before;
- private Region after;
- private Region start;
- private Region end;
+ private RegionArea body;
+ private RegionArea before;
+ private RegionArea after;
+ private RegionArea start;
+ private RegionArea end;
public PageMaster(int pageWidth, int pageHeight) {
this.width = pageWidth;
this.height = pageHeight;
}
- public void addAfter(Region region) {
+ public void addAfter(RegionArea region) {
this.after = region;
}
- public void addBefore(Region region) {
+ public void addBefore(RegionArea region) {
this.before = region;
}
- public void addBody(Region region) {
+ public void addBody(RegionArea region) {
this.body = region;
}
- public void addEnd(Region region) {
+ public void addEnd(RegionArea region) {
this.end = region;
}
- public void addStart(Region region) {
+ public void addStart(RegionArea region) {
this.start = region;
}
diff --git a/src/org/apache/fop/layout/Region.java b/src/org/apache/fop/layout/RegionArea.java
index 634960e4e..d044c4f74 100644
--- a/src/org/apache/fop/layout/Region.java
+++ b/src/org/apache/fop/layout/RegionArea.java
@@ -51,14 +51,14 @@
package org.apache.fop.layout;
import org.apache.fop.fo.properties.*;
-public class Region {
+public class RegionArea {
private int xPosition;
private int yPosition;
private int width;
private int height;
- public Region(int xPosition, int yPosition, int width, int height) {
+ public RegionArea(int xPosition, int yPosition, int width, int height) {
this.xPosition = xPosition;
this.yPosition = yPosition;
this.width = width;
diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java
index ed14299e8..0de1cfab0 100644
--- a/src/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/org/apache/fop/render/pdf/PDFRenderer.java
@@ -174,7 +174,9 @@ public class PDFRenderer implements Renderer {
}
if ( !idReferences.isEveryIdValid() ) {
- throw new FOPException("The following id's were referenced but not found: "+idReferences.getInvalidIds()+"\n");
+ // throw new FOPException("The following id's were referenced but not found: "+idReferences.getInvalidIds()+"\n");
+ MessageHandler.errorln("WARNING: The following id's were referenced but not found: "+idReferences.getInvalidIds()+"\n");
+
}
MessageHandler.logln("writing out PDF");