--- /dev/null
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.fo.flow;
+
+// FOP
+import org.apache.fop.fo.*;
+import org.apache.fop.fo.properties.*;
+import org.apache.fop.fo.pagination.*;
+import org.apache.fop.layout.Area;
+import org.apache.fop.layout.BodyAreaContainer;
+import org.apache.fop.apps.FOPException;
+
+// Java
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Vector;
+
+public abstract class AbstractFlow extends FObj {
+
+ /**
+ * PageSequence container
+ */
+ protected PageSequence pageSequence;
+
+ /**
+ * Area in which we lay out our kids
+ */
+ private Area area;
+
+ /**
+ * Vector to store snapshot
+ */
+ private Vector markerSnapshot;
+
+ /**
+ * flow-name attribute
+ */
+ protected String _flowName;
+
+ /**
+ * Content-width of current column area during layout
+ */
+ private int contentWidth;
+
+ private Status _status = new Status(Status.AREA_FULL_NONE);
+
+
+ protected AbstractFlow(FObj parent,
+ PropertyList propertyList) throws FOPException {
+ super(parent, propertyList);
+
+ if (parent.getName().equals("fo:page-sequence")) {
+ this.pageSequence = (PageSequence)parent;
+ } else {
+ throw new FOPException("flow must be child of page-sequence, not "
+ + parent.getName());
+ }
+ }
+
+ 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;
+ }
+
+ // flow is *always* laid out into a BodyAreaContainer
+ BodyAreaContainer bac = (BodyAreaContainer)area;
+
+ boolean prevChildMustKeepWithNext = false;
+ Vector pageMarker = this.getMarkerSnapshot(new Vector());
+
+ int numChildren = this.children.size();
+ if (numChildren == 0) {
+ throw new FOPException("fo:flow must contain block-level children");
+ }
+ for (int i = this.marker; i < numChildren; i++) {
+ FObj fo = (FObj)children.elementAt(i);
+
+ if (bac.isBalancingRequired(fo)) {
+ // reset the the just-done span area in preparation
+ // for a backtrack for balancing
+ bac.resetSpanArea();
+
+ this.rollback(markerSnapshot);
+ // one less because of the "continue"
+ i = this.marker - 1;
+ continue;
+ }
+ // current column area
+ Area currentArea = bac.getNextArea(fo);
+ // temporary hack for IDReferences
+ currentArea.setIDReferences(bac.getIDReferences());
+ if (bac.isNewSpanArea()) {
+ this.marker = i;
+ markerSnapshot = this.getMarkerSnapshot(new Vector());
+ }
+ // Set current content width for percent-based lengths in children
+ setContentWidth(currentArea.getContentWidth());
+
+ _status = fo.layout(currentArea);
+
+ /*
+ * if((_status.isPageBreak() || i == numChildren - 1) && bac.needsFootnoteAdjusting()) {
+ * bac.adjustFootnoteArea();
+ * this.rollback(pageMarker);
+ * i = this.marker - 1;
+ * Area mainReferenceArea = bac.getMainReferenceArea();
+ * // remove areas
+ * continue;
+ * }
+ */
+ if (_status.isIncomplete()) {
+ if ((prevChildMustKeepWithNext) && (_status.laidOutNone())) {
+ this.marker = i - 1;
+ FObj prevChild = (FObj)children.elementAt(this.marker);
+ prevChild.removeAreas();
+ prevChild.resetMarker();
+ prevChild.removeID(area.getIDReferences());
+ _status = new Status(Status.AREA_FULL_SOME);
+ return _status;
+ // should probably return AREA_FULL_NONE if first
+ // or perhaps an entirely new status code
+ }
+ if (bac.isLastColumn())
+ if (_status.getCode() == Status.FORCE_COLUMN_BREAK) {
+ this.marker = i;
+ _status =
+ new Status(Status.FORCE_PAGE_BREAK); // same thing
+ return _status;
+ } else {
+ this.marker = i;
+ return _status;
+ }
+ else {
+ // not the last column, but could be page breaks
+ if (_status.isPageBreak()) {
+ this.marker = i;
+ return _status;
+ }
+ // I don't much like exposing this. (AHS 001217)
+ ((org.apache.fop.layout.ColumnArea)currentArea).incrementSpanIndex();
+ i--;
+ }
+ }
+ if (_status.getCode() == Status.KEEP_WITH_NEXT) {
+ prevChildMustKeepWithNext = true;
+ } else {
+ prevChildMustKeepWithNext = false;
+ }
+ }
+ return _status;
+ }
+
+ protected void setContentWidth(int contentWidth) {
+ this.contentWidth = contentWidth;
+ }
+ /**
+ * Return the content width of this flow (really of the region
+ * in which it is flowing).
+ */
+ public int getContentWidth() {
+ return this.contentWidth;
+ }
+
+ public Status getStatus() {
+ return _status;
+ }
+
+
+ public boolean generatesReferenceAreas() {
+ return true;
+ }
+
+}
import org.apache.fop.fo.properties.*;
import org.apache.fop.fo.pagination.*;
import org.apache.fop.layout.Area;
-import org.apache.fop.layout.BodyAreaContainer;
import org.apache.fop.apps.FOPException;
-// Java
-import java.util.Hashtable;
-import java.util.Enumeration;
-import java.util.Vector;
-
-public class Flow extends FObj {
+public class Flow extends AbstractFlow {
public static class Maker extends FObj.Maker {
public FObj make(FObj parent,
PropertyList propertyList) throws FOPException {
return new Flow(parent, propertyList);
}
-
}
public static FObj.Maker maker() {
return new Flow.Maker();
}
- /**
- * PageSequence container
- */
- private PageSequence pageSequence;
-
- /**
- * Area in which we lay out our kids
- */
- private Area area;
-
- /**
- * Vector to store snapshot
- */
- private Vector markerSnapshot;
-
- /**
- * flow-name attribute
- */
- private String _flowName;
-
- /**
- * Content-width of current column area during layout
- */
- private int contentWidth;
-
- private Status _status = new Status(Status.AREA_FULL_NONE);
-
-
protected Flow(FObj parent,
PropertyList propertyList) throws FOPException {
super(parent, propertyList);
-
- if (parent.getName().equals("fo:page-sequence")) {
- this.pageSequence = (PageSequence)parent;
- } else {
- throw new FOPException("flow must be child of page-sequence, not "
- + parent.getName());
- }
setFlowName(getProperty("flow-name").getString());
-
- // according to communication from Paul Grosso (XSL-List,
- // 001228, Number 406), confusion in spec section 6.4.5 about
- // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1)
- // fo:flow per fo:page-sequence only.
-
- if (pageSequence.isFlowSet()) {
- if (getName().equals("fo:flow")) {
- throw new FOPException("Only a single fo:flow permitted"
- + " per fo:page-sequence");
- } else {
- throw new FOPException(getName()
- + " not allowed after fo:flow");
- }
- }
pageSequence.addFlow(this);
}
}
- 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;
- }
-
- // flow is *always* laid out into a BodyAreaContainer
- BodyAreaContainer bac = (BodyAreaContainer)area;
-
- boolean prevChildMustKeepWithNext = false;
- Vector pageMarker = this.getMarkerSnapshot(new Vector());
-
- int numChildren = this.children.size();
- if (numChildren == 0) {
- throw new FOPException("fo:flow must contain block-level children");
- }
- for (int i = this.marker; i < numChildren; i++) {
- FObj fo = (FObj)children.elementAt(i);
-
- if (bac.isBalancingRequired(fo)) {
- // reset the the just-done span area in preparation
- // for a backtrack for balancing
- bac.resetSpanArea();
-
- this.rollback(markerSnapshot);
- // one less because of the "continue"
- i = this.marker - 1;
- continue;
- }
- // current column area
- Area currentArea = bac.getNextArea(fo);
- // temporary hack for IDReferences
- currentArea.setIDReferences(bac.getIDReferences());
- if (bac.isNewSpanArea()) {
- this.marker = i;
- markerSnapshot = this.getMarkerSnapshot(new Vector());
- }
- // Set current content width for percent-based lengths in children
- setContentWidth(currentArea.getContentWidth());
-
- _status = fo.layout(currentArea);
-
- /*
- * if((_status.isPageBreak() || i == numChildren - 1) && bac.needsFootnoteAdjusting()) {
- * bac.adjustFootnoteArea();
- * this.rollback(pageMarker);
- * i = this.marker - 1;
- * Area mainReferenceArea = bac.getMainReferenceArea();
- * // remove areas
- * continue;
- * }
- */
- if (_status.isIncomplete()) {
- if ((prevChildMustKeepWithNext) && (_status.laidOutNone())) {
- this.marker = i - 1;
- FObj prevChild = (FObj)children.elementAt(this.marker);
- prevChild.removeAreas();
- prevChild.resetMarker();
- prevChild.removeID(area.getIDReferences());
- _status = new Status(Status.AREA_FULL_SOME);
- return _status;
- // should probably return AREA_FULL_NONE if first
- // or perhaps an entirely new status code
- }
- if (bac.isLastColumn())
- if (_status.getCode() == Status.FORCE_COLUMN_BREAK) {
- this.marker = i;
- _status =
- new Status(Status.FORCE_PAGE_BREAK); // same thing
- return _status;
- } else {
- this.marker = i;
- return _status;
- }
- else {
- // not the last column, but could be page breaks
- if (_status.isPageBreak()) {
- this.marker = i;
- return _status;
- }
- // I don't much like exposing this. (AHS 001217)
- ((org.apache.fop.layout.ColumnArea)currentArea).incrementSpanIndex();
- i--;
- }
- }
- if (_status.getCode() == Status.KEEP_WITH_NEXT) {
- prevChildMustKeepWithNext = true;
- } else {
- prevChildMustKeepWithNext = false;
- }
- }
- return _status;
- }
-
- protected void setContentWidth(int contentWidth) {
- this.contentWidth = contentWidth;
- }
- /**
- * Return the content width of this flow (really of the region
- * in which it is flowing).
- */
- public int getContentWidth() {
- return this.contentWidth;
- }
-
- public Status getStatus() {
- return _status;
- }
-
-
- public boolean generatesReferenceAreas() {
- return true;
- }
-
}
import org.apache.fop.layout.Area;
import org.apache.fop.apps.FOPException;
-// Java
-import java.util.Enumeration;
-
-public class StaticContent extends Flow {
+public class StaticContent extends AbstractFlow {
public static class Maker extends FObj.Maker {
public FObj make(FObj parent,
PropertyList propertyList) throws FOPException {
return new StaticContent(parent, propertyList);
}
-
}
public static FObj.Maker maker() {
protected StaticContent(FObj parent,
PropertyList propertyList) throws FOPException {
super(parent, propertyList);
- ((PageSequence)parent).setIsFlowSet(false); // hacquery of sorts
+ setFlowName(getProperty("flow-name").getString());
+ pageSequence.addStaticContent(this);
+// ((PageSequence)parent).setIsFlowSet(false); // hacquery of sorts
}
public String getName() {
return "fo:static-content";
}
- 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();
throw new FOPException("A 'flow-name' is required for "
+ getName() + ".");
} else {
- super.setFlowName(name);
+ _flowName = name;
}
}
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/
-/*
- Modified by Mark Lillywhite mark-fop@inomial.com. Does not add
- itself to the root any more. Does not hang onto currentPage
- pointer, which caused GC issues.
- */
package org.apache.fop.fo.pagination;
private static final int AUTO_EVEN = 2;
private static final int AUTO_ODD = 3;
- //
- // associations
- //
-
/**
* The parent root object
*/
/**
* Map of flows to their flow name (flow-name, Flow)
+ * Does only contain flows for static content!
*/
- private Hashtable _flowMap;
+ private Hashtable flowMap;
+
+ // according to communication from Paul Grosso (XSL-List,
+ // 001228, Number 406), confusion in spec section 6.4.5 about
+ // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1)
+ // fo:flow per fo:page-sequence only.
+ private Flow flow = null;
/**
* the "master-reference" attribute,
*/
private String masterName;
- // according to communication from Paul Grosso (XSL-List,
- // 001228, Number 406), confusion in spec section 6.4.5 about
- // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1)
- // fo:flow per fo:page-sequence only.
- private boolean isFlowSet = false;
-
- //
- // state attributes used during layout
- //
-
// page number and related formatting variables
private int firstPageNumber = 0;
private PageNumberGenerator pageNumberGenerator;
- private int forcePageCount;
private int pageCount = 0;
private int currentPageNumber;
*/
private int pageNumberType;
+ private int forcePageCountType;
+
/**
* the current page master
*/
// best time to run some checks on LayoutMasterSet
layoutMasterSet.checkRegionNames();
- _flowMap = new Hashtable();
+ flowMap = new Hashtable();
String ipnValue = this.properties.get("initial-page-number").getString();
this.properties.get("grouping-size").getNumber().intValue(),
this.properties.get("letter-value").getEnum());
- this.forcePageCount =
+ this.forcePageCountType =
this.properties.get("force-page-count").getEnum();
// this.properties.get("country");
}
public void addFlow(Flow flow) throws FOPException {
- if (_flowMap.containsKey(flow.getFlowName())) {
+ if (this.flow!=null) {
+ throw new FOPException("Only a single fo:flow permitted per fo:page-sequence");
+ }
+ if (flowMap.containsKey(flow.getFlowName())) {
+ throw new FOPException("flow-names must be unique within an fo:page-sequence");
+ }
+ this.flow = flow;
+ }
+
+
+ public void addStaticContent(StaticContent staticContent) throws FOPException {
+ if (this.flow!=null) {
+ throw new FOPException("Static content ('"
+ + staticContent.getFlowName()
+ + "') is not allowed after fo:flow");
+ }
+ if (flowMap.containsKey(staticContent.getFlowName())) {
throw new FOPException("flow-names must be unique within an fo:page-sequence");
}
- if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) {
+ if (!this.layoutMasterSet.regionNameExists(staticContent.getFlowName())) {
log.error("region-name '"
- + flow.getFlowName()
+ + staticContent.getFlowName()
+ "' doesn't exist in the layout-master-set.");
}
- _flowMap.put(flow.getFlowName(), flow);
- setIsFlowSet(true);
+ flowMap.put(staticContent.getFlowName(), staticContent);
}
public void format(AreaTree areaTree) throws FOPException {
PageSequence previousPageSequence=this.root.getPageSequence();
if( previousPageSequence!=null ) {
- if (previousPageSequence.forcePageCount == ForcePageCount.AUTO) {
+ if (previousPageSequence.forcePageCountType == ForcePageCount.AUTO) {
if (pageNumberType == AUTO_ODD) {
if (previousPageSequence.currentPageNumber % 2 == 0) {
previousPageSequence.makePage(areaTree,true,null);
+ "' for fo:page-sequence matches no simple-page-master or page-sequence-master");
}
pageSequenceMaster.reset();
+ } else {
+ Region region = currentSimplePageMaster
+ .getRegion(RegionBody.REGION_CLASS);
+ if (!flow.getFlowName().equals(region.getRegionName())) {
+ throw new FOPException("Flow '" + flow.getFlowName()
+ + "' does not map to the region-body in page-master '"
+ + currentSimplePageMaster.getMasterName() + "'");
+ }
}
// make pages and layout content
Status status = new Status(Status.OK);
- Page lastPage = null;
+ Page currentPage = null;
do {
boolean isBlankPage = false;
isBlankPage = true;
}
}
- lastPage = makePage(areaTree, isBlankPage, lastPage);
- // Hackery, should use special variable for flow
- Region region = currentSimplePageMaster
- .getRegion(RegionBody.REGION_CLASS);
- Flow flow = (Flow)_flowMap.get(region.getRegionName());
+ currentPage = makePage(areaTree, isBlankPage, currentPage);
status = flow.getStatus();
- } while (flowsAreIncomplete());
+ } while (status.isIncomplete());
// handle cases of 'force-page-count' which do not depend
// on the presence of a following page sequence
- if (this.forcePageCount == ForcePageCount.EVEN) {
+ if (this.forcePageCountType == ForcePageCount.EVEN) {
if (this.pageCount % 2 != 0) {
makePage(areaTree,true, null);
}
- } else if (this.forcePageCount == ForcePageCount.ODD) {
+ } else if (this.forcePageCountType == ForcePageCount.ODD) {
if (this.pageCount % 2 != 1) {
makePage(areaTree,true, null);
}
- } else if (this.forcePageCount == ForcePageCount.END_ON_EVEN) {
+ } else if (this.forcePageCountType == ForcePageCount.END_ON_EVEN) {
if (this.currentPageNumber % 2 == 0) {
makePage(areaTree,true, null);
}
- } else if (this.forcePageCount == ForcePageCount.END_ON_ODD) {
+ } else if (this.forcePageCountType == ForcePageCount.END_ON_ODD) {
if (this.currentPageNumber % 2 == 1) {
makePage(areaTree,true, null);
}
* @return a Page layout object based on the page master selected from the params
*/
private Page makePage(AreaTree areaTree,
- boolean isBlankPage,
- Page lastPage)
+ boolean isBlankPage,
+ Page currentPage)
throws FOPException {
if (this.pageSequenceMaster!=null) {
this.currentSimplePageMaster=this.pageSequenceMaster
.getNextSimplePageMaster(((this.currentPageNumber % 2)==1),
isBlankPage);
+ Region region = currentSimplePageMaster
+ .getRegion(RegionBody.REGION_CLASS);
+ if (!flow.getFlowName().equals(region.getRegionName())) {
+ throw new FOPException("Flow '" + flow.getFlowName()
+ + "' does not map to the region-body in page-master '"
+ + currentSimplePageMaster.getMasterName() + "'");
+ }
}
Page newPage = this.currentSimplePageMaster.getPageMaster()
.makePage(areaTree);
- if (lastPage != null) {
- Vector foots = lastPage.getPendingFootnotes();
+ if (currentPage != null) {
+ Vector foots = currentPage.getPendingFootnotes();
newPage.setPendingFootnotes(foots);
}
newPage.setNumber(this.currentPageNumber);
pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber);
newPage.setFormattedNumber(formattedPageNumber);
newPage.setPageSequence(this);
- log.info("[" + currentPageNumber + (isBlankPage?"(forced)]":"]"));
if (!isBlankPage) {
+ log.info("[" + currentPageNumber + "]");
BodyAreaContainer bodyArea = newPage.getBody();
bodyArea.setIDReferences(areaTree.getIDReferences());
-
- Region region = currentSimplePageMaster
- .getRegion(RegionBody.REGION_CLASS);
- Flow flow = (Flow)_flowMap.get(region.getRegionName());
- if (flow != null) {
- flow.layout(bodyArea);
- } else {
- throw new FOPException("No flow found for region-body in page-master '"
- + currentSimplePageMaster.getMasterName() + "'");
- }
+ flow.layout(bodyArea);
+ } else {
+ log.info("[" + currentPageNumber + " (blank)]");
}
// because of markers, do after fo:flow (likely also
// justifiable because of spec)
if (simpleMaster.getRegion(RegionBefore.REGION_CLASS) != null
&& (page.getBefore() != null)) {
- Flow staticFlow =
- (Flow)_flowMap.get(simpleMaster.getRegion(RegionBefore.REGION_CLASS).getRegionName());
+ StaticContent staticFlow =
+ (StaticContent)flowMap.get(simpleMaster.getRegion(RegionBefore.REGION_CLASS).getRegionName());
if (staticFlow != null) {
AreaContainer beforeArea = page.getBefore();
beforeArea.setIDReferences(areaTree.getIDReferences());
if (simpleMaster.getRegion(RegionAfter.REGION_CLASS) != null
&& (page.getAfter() != null)) {
- Flow staticFlow =
- (Flow)_flowMap.get(simpleMaster.getRegion(RegionAfter.REGION_CLASS).getRegionName());
+ StaticContent staticFlow =
+ (StaticContent)flowMap.get(simpleMaster.getRegion(RegionAfter.REGION_CLASS).getRegionName());
if (staticFlow != null) {
AreaContainer afterArea = page.getAfter();
afterArea.setIDReferences(areaTree.getIDReferences());
if (simpleMaster.getRegion(RegionStart.REGION_CLASS) != null
&& (page.getStart() != null)) {
- Flow staticFlow =
- (Flow)_flowMap.get(simpleMaster.getRegion(RegionStart.REGION_CLASS).getRegionName());
+ StaticContent staticFlow =
+ (StaticContent)flowMap.get(simpleMaster.getRegion(RegionStart.REGION_CLASS).getRegionName());
if (staticFlow != null) {
AreaContainer startArea = page.getStart();
startArea.setIDReferences(areaTree.getIDReferences());
if (simpleMaster.getRegion(RegionEnd.REGION_CLASS) != null
&& (page.getEnd() != null)) {
- Flow staticFlow =
- (Flow)_flowMap.get(simpleMaster.getRegion(RegionEnd.REGION_CLASS).getRegionName());
+ StaticContent staticFlow =
+ (StaticContent)flowMap.get(simpleMaster.getRegion(RegionEnd.REGION_CLASS).getRegionName());
if (staticFlow != null) {
AreaContainer endArea = page.getEnd();
endArea.setIDReferences(areaTree.getIDReferences());
}
- private void layoutStaticContent(Flow flow, Region region,
+ private void layoutStaticContent(StaticContent flow, Region region,
AreaContainer area) throws FOPException {
- if (flow instanceof StaticContent) {
- ((StaticContent)flow).layout(area, region);
- } else {
- log.error("The region '" + region.getRegionName()
- + "' only supports static-content. Cannot use flow named '"
- + flow.getFlowName() + "'");
- }
- }
-
- /**
- * Returns true when there are more flow elements left to lay out.
- */
- private boolean flowsAreIncomplete() {
- for (Enumeration e = _flowMap.elements(); e.hasMoreElements(); ) {
- Flow flow = (Flow)e.nextElement();
- if (flow instanceof StaticContent) {
- continue;
- }
- if (flow.getStatus().isIncomplete()) {
- return true;
- }
- }
- return false;
- }
-
- public boolean isFlowSet() {
- return isFlowSet;
- }
-
- public void setIsFlowSet(boolean isFlowSet) {
- this.isFlowSet = isFlowSet;
+ flow.layout(area, region);
+// log.error("The region '" + region.getRegionName()
+// + "' only supports static-content. Cannot use flow named '"
+// + flow.getFlowName() + "'");
}
public int getCurrentPageNumber() {