aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop/fo
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/apache/fop/fo')
-rw-r--r--src/org/apache/fop/fo/ElementMapping.java6
-rw-r--r--src/org/apache/fop/fo/FONode.java110
-rw-r--r--src/org/apache/fop/fo/FOText.java80
-rw-r--r--src/org/apache/fop/fo/FOTreeBuilder.java204
-rw-r--r--src/org/apache/fop/fo/FObj.java57
-rw-r--r--src/org/apache/fop/fo/FObjMixed.java49
-rw-r--r--src/org/apache/fop/fo/Makefile33
-rw-r--r--src/org/apache/fop/fo/Property.java41
-rw-r--r--src/org/apache/fop/fo/PropertyList.java41
-rw-r--r--src/org/apache/fop/fo/PropertyListBuilder.java120
-rw-r--r--src/org/apache/fop/fo/StandardElementMapping.java52
-rw-r--r--src/org/apache/fop/fo/flow/Block.java192
-rw-r--r--src/org/apache/fop/fo/flow/DisplayGraphic.java132
-rw-r--r--src/org/apache/fop/fo/flow/DisplayRule.java88
-rw-r--r--src/org/apache/fop/fo/flow/DisplaySequence.java52
-rw-r--r--src/org/apache/fop/fo/flow/Flow.java59
-rw-r--r--src/org/apache/fop/fo/flow/InlineSequence.java35
-rw-r--r--src/org/apache/fop/fo/flow/ListBlock.java143
-rw-r--r--src/org/apache/fop/fo/flow/ListItem.java144
-rw-r--r--src/org/apache/fop/fo/flow/ListItemBody.java54
-rw-r--r--src/org/apache/fop/fo/flow/ListItemLabel.java49
-rw-r--r--src/org/apache/fop/fo/flow/Makefile39
-rw-r--r--src/org/apache/fop/fo/flow/PageNumber.java66
-rw-r--r--src/org/apache/fop/fo/flow/StaticContent.java54
-rw-r--r--src/org/apache/fop/fo/flow/Table.java183
-rw-r--r--src/org/apache/fop/fo/flow/TableBody.java137
-rw-r--r--src/org/apache/fop/fo/flow/TableCell.java122
-rw-r--r--src/org/apache/fop/fo/flow/TableColumn.java34
-rw-r--r--src/org/apache/fop/fo/flow/TableRow.java155
-rw-r--r--src/org/apache/fop/fo/pagination/LayoutMasterSet.java50
-rw-r--r--src/org/apache/fop/fo/pagination/Makefile36
-rw-r--r--src/org/apache/fop/fo/pagination/PageSequence.java138
-rw-r--r--src/org/apache/fop/fo/pagination/RegionAfter.java54
-rw-r--r--src/org/apache/fop/fo/pagination/RegionBefore.java53
-rw-r--r--src/org/apache/fop/fo/pagination/RegionBody.java50
-rw-r--r--src/org/apache/fop/fo/pagination/Root.java61
-rw-r--r--src/org/apache/fop/fo/pagination/SequenceSpecification.java66
-rw-r--r--src/org/apache/fop/fo/pagination/SequenceSpecifier.java13
-rw-r--r--src/org/apache/fop/fo/pagination/SequenceSpecifierAlternating.java65
-rw-r--r--src/org/apache/fop/fo/pagination/SequenceSpecifierRepeating.java61
-rw-r--r--src/org/apache/fop/fo/pagination/SequenceSpecifierSingle.java59
-rw-r--r--src/org/apache/fop/fo/pagination/SimplePageMaster.java89
42 files changed, 3326 insertions, 0 deletions
diff --git a/src/org/apache/fop/fo/ElementMapping.java b/src/org/apache/fop/fo/ElementMapping.java
new file mode 100644
index 000000000..04fc3a0eb
--- /dev/null
+++ b/src/org/apache/fop/fo/ElementMapping.java
@@ -0,0 +1,6 @@
+package org.apache.xml.fop.fo;
+
+public interface ElementMapping {
+
+ public void addToBuilder(FOTreeBuilder builder);
+}
diff --git a/src/org/apache/fop/fo/FONode.java b/src/org/apache/fop/fo/FONode.java
new file mode 100644
index 000000000..ede968d78
--- /dev/null
+++ b/src/org/apache/fop/fo/FONode.java
@@ -0,0 +1,110 @@
+package org.apache.xml.fop.fo;
+
+// FOP
+import org.apache.xml.fop.apps.FOPException;
+import org.apache.xml.fop.layout.Area;
+
+// Java
+import java.util.Vector;
+
+/**
+ * base class for nodes in the formatting object tree
+ */
+abstract public class FONode {
+
+ protected FObj parent;
+ protected Vector children = new Vector();
+
+ /** value of marker before layout begins */
+ public final static int START = -1000;
+
+ /** value of marker after break-after */
+ public final static int BREAK_AFTER = -1001;
+
+ /**
+ * where the layout was up to.
+ * for FObjs it is the child number
+ * for FOText it is the character number
+ */
+ protected int marker = START;
+
+ protected boolean isInLabel = false;
+ protected boolean isInListBody = false;
+ protected boolean isInTableCell = false;
+
+ protected int bodyIndent;
+ protected int distanceBetweenStarts;
+ protected int labelSeparation;
+
+ protected int forcedStartOffset = 0;
+ protected int forcedWidth = 0;
+
+ protected FONode(FObj parent) {
+ this.parent = parent;
+ }
+
+ public void setIsInLabel() {
+ this.isInLabel = true;
+ }
+
+ public void setIsInListBody() {
+ this.isInListBody = true;
+ }
+
+ public void setIsInTableCell() {
+ this.isInTableCell = true;
+ }
+
+ public void setDistanceBetweenStarts(int distance) {
+ this.distanceBetweenStarts = distance;
+ }
+
+ public void setLabelSeparation(int separation) {
+ this.labelSeparation = separation;
+ }
+
+ public void setBodyIndent(int indent) {
+ this.bodyIndent = indent;
+ }
+
+ public void forceStartOffset(int offset) {
+ this.forcedStartOffset = offset;
+ }
+
+ public void forceWidth(int width) {
+ this.forcedWidth = width;
+ }
+
+ public void resetMarker() {
+ this.marker = START;
+ int numChildren = this.children.size();
+ for (int i = 0; i < numChildren; i++) {
+ ((FONode) children.elementAt(i)).resetMarker();
+ }
+ }
+
+ protected void addChild(FONode child) {
+ children.addElement(child);
+ }
+
+ public FObj getParent() {
+ return this.parent;
+ }
+
+ /* status */
+ /* layout was fully completed */
+ public final static int OK = 1;
+ /* none of the formatting object could be laid out because the
+ containing area was full (end of page) */
+ public final static int AREA_FULL_NONE = 2;
+ /* some of the formatting object could not be laid out because the
+ containing area was full (end of page) */
+ public final static int AREA_FULL_SOME = 3;
+ /* force page break */
+ public final static int FORCE_PAGE_BREAK = 4;
+ public final static int FORCE_PAGE_BREAK_EVEN = 5;
+ public final static int FORCE_PAGE_BREAK_ODD = 6;
+
+ abstract public int layout(Area area)
+ throws FOPException;
+}
diff --git a/src/org/apache/fop/fo/FOText.java b/src/org/apache/fop/fo/FOText.java
new file mode 100644
index 000000000..f61995a88
--- /dev/null
+++ b/src/org/apache/fop/fo/FOText.java
@@ -0,0 +1,80 @@
+package org.apache.xml.fop.fo;
+
+// FOP
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.BlockArea;
+import org.apache.xml.fop.layout.FontState;
+import org.apache.xml.fop.datatypes.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.apps.FOPException;
+
+/**
+ * a text node in the formatting object tree
+ */
+public class FOText extends FONode {
+
+ protected char[] ca;
+ protected int start;
+ protected int length;
+
+ FontState fs;
+ float red;
+ float green;
+ float blue;
+ int wrapOption;
+ int whiteSpaceTreatment;
+
+ protected FOText(char[] chars, int s, int e, FObj parent) {
+ super(parent);
+ this.start = 0;
+ this.ca = new char[e - s];
+ for (int i = s; i < e; i++)
+ this.ca[i - s] = chars[i];
+ this.length = e - s;
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (!(area instanceof BlockArea)) {
+ System.err.println("WARNING: text outside block area" + new String(ca, start, length));
+ return OK;
+ }
+ if (this.marker == START) {
+ String fontFamily =
+ this.parent.properties.get("font-family").getString();
+ String fontStyle =
+ this.parent.properties.get("font-style").getString();
+ String fontWeight =
+ this.parent.properties.get("font-weight").getString();
+ int fontSize =
+ this.parent.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily, fontStyle,
+ fontWeight, fontSize);
+
+ ColorType c =
+ this.parent.properties.get("color").getColorType();
+ this.red = c.red();
+ this.green = c.green();
+ this.blue = c.blue();
+
+ this.wrapOption =
+ this.parent.properties.get("wrap-option").getEnum();
+ this.whiteSpaceTreatment =
+ this.parent.properties.get("white-space-treatment").getEnum();
+
+ this.marker = this.start;
+ }
+ int orig_start = this.marker;
+ this.marker = ((BlockArea) area).addText(fs, red, green, blue,
+ wrapOption,
+ whiteSpaceTreatment,
+ ca, this.marker, length);
+ if (this.marker == -1) {
+ return OK;
+ } else if (this.marker != orig_start) {
+ return AREA_FULL_SOME;
+ } else {
+ return AREA_FULL_NONE;
+ }
+ }
+}
diff --git a/src/org/apache/fop/fo/FOTreeBuilder.java b/src/org/apache/fop/fo/FOTreeBuilder.java
new file mode 100644
index 000000000..d4a1f5d09
--- /dev/null
+++ b/src/org/apache/fop/fo/FOTreeBuilder.java
@@ -0,0 +1,204 @@
+package org.apache.xml.fop.fo;
+
+// FOP
+import org.apache.xml.fop.layout.AreaTree;
+import org.apache.xml.fop.apps.FOPException;
+import org.apache.xml.fop.fo.pagination.Root;
+
+// SAX
+import org.xml.sax.HandlerBase;
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
+import org.xml.sax.AttributeList;
+
+// Java
+import java.util.Hashtable;
+import java.util.Stack;
+import java.io.IOException;
+
+/**
+ * SAX Handler that builds the formatting object tree.
+ */
+public class FOTreeBuilder extends HandlerBase {
+
+ /**
+ * table mapping element names to the makers of objects
+ * representing formatting objects
+ */
+ protected Hashtable fobjTable = new Hashtable();
+
+ /**
+ * class that builds a property list for each formatting object
+ */
+ protected PropertyListBuilder propertyListBuilder = new
+ PropertyListBuilder();
+
+ /**
+ * current formatting object being handled
+ */
+ protected FObj currentFObj = null;
+
+ /**
+ * the root of the formatting object tree
+ */
+ protected FObj rootFObj = null;
+
+ /**
+ * set of names of formatting objects encountered but unknown
+ */
+ protected Hashtable unknownFOs = new Hashtable();
+
+ // namespace implementation ideas pinched from John Cowan
+ protected static class NSMap {
+ String prefix;
+ String uri;
+ int level;
+
+ NSMap(String prefix, String uri, int level) {
+ this.prefix = prefix;
+ this.uri = uri;
+ this.level = level;
+ }
+ }
+
+ protected int level = 0;
+ protected Stack namespaceStack = new Stack();
+
+ {
+ namespaceStack.push(new NSMap("xml",
+ "http://www.w3.org/XML/1998/namespace",
+ -1));
+ namespaceStack.push(new NSMap("", "", -1));
+ }
+
+ protected String findURI(String prefix) {
+ for (int i = namespaceStack.size() - 1; i >= 0; i--) {
+ NSMap nsMap = (NSMap) (namespaceStack.elementAt(i));
+ if (prefix.equals(nsMap.prefix)) return nsMap.uri;
+ }
+ return null;
+ }
+
+ protected String mapName(String name)
+ throws SAXException {
+ int colon = name.indexOf(':');
+ String prefix = "";
+ String localPart = name;
+ if (colon != -1) {
+ prefix = name.substring(0, colon);
+ localPart = name.substring(colon + 1);
+ }
+ String uri = findURI(prefix);
+ if (uri == null) {
+ if (prefix.equals("")) {
+ return name;
+ } else {
+ throw new SAXException(new FOPException("Unknown namespace prefix " + prefix));
+ }
+ }
+ return uri + "^" + localPart;
+ }
+
+ /**
+ * add a mapping from element name to maker.
+ *
+ * @param namespaceURI namespace URI of formatting object element
+ * @param localName local name of formatting object element
+ * @param maker Maker for class representing formatting object
+ */
+ public void addMapping(String namespaceURI, String localName,
+ FObj.Maker maker) {
+ this.fobjTable.put(namespaceURI + "^" + localName, maker);
+ }
+
+ /** SAX Handler for characters */
+ public void characters(char data[], int start, int length) {
+ currentFObj.addCharacters(data, start, start + length);
+ }
+
+ /** SAX Handler for the end of an element */
+ public void endElement(String name) {
+ currentFObj.end();
+ currentFObj = (FObj) currentFObj.getParent();
+ level--;
+ while (((NSMap) namespaceStack.peek()).level > level) {
+ namespaceStack.pop();
+ }
+ }
+
+ /** SAX Handler for the start of the document */
+ public void startDocument() {
+ System.err.println("building formatting object tree");
+ }
+
+ /** SAX Handler for the start of an element */
+ public void startElement(String name, AttributeList attlist)
+ throws SAXException {
+
+ /* the formatting object started */
+ FObj fobj;
+
+ /* the maker for the formatting object started */
+ FObj.Maker fobjMaker;
+
+ level++;
+ int length = attlist.getLength();
+ for (int i = 0; i < length; i++) {
+ String att = attlist.getName(i);
+ if (att.equals("xmlns")) {
+ namespaceStack.push( new NSMap("",
+ attlist.getValue(i),
+ level));
+ } else if (att.startsWith("xmlns:")) {
+ String value = attlist.getValue(i);
+ namespaceStack.push(new NSMap(att.substring(6), value,
+ level));
+ }
+ }
+ String fullName = mapName(name);
+
+ fobjMaker = (FObj.Maker) fobjTable.get(fullName);
+
+ if (fobjMaker == null) {
+ if (!this.unknownFOs.containsKey(fullName)) {
+ this.unknownFOs.put(fullName, "");
+ System.err.println("WARNING: Unknown formatting object "
+ + fullName);
+ }
+ fobjMaker = new FObjMixed.Maker(); // fall back
+ }
+
+ try {
+ fobj =
+ fobjMaker.make(currentFObj,
+ this.propertyListBuilder.makeList(attlist,
+ (currentFObj == null) ? null : currentFObj.properties));
+ } catch (FOPException e) {
+ throw new SAXException(e);
+ }
+
+ if (rootFObj == null) {
+ rootFObj = fobj;
+ if (!fobj.getName().equals("fo:root")) {
+ throw new SAXException(new FOPException("Root element must"
+ + " be root, not "
+ + fobj.getName()));
+ }
+ } else {
+ currentFObj.addChild(fobj);
+ }
+
+ currentFObj = fobj;
+ }
+
+ /**
+ * format this formatting object tree
+ *
+ * @param areaTree the area tree to format into
+ */
+ public void format(AreaTree areaTree)
+ throws FOPException {
+ System.err.println("formatting FOs into areas");
+ ((Root) this.rootFObj).format(areaTree);
+ }
+}
diff --git a/src/org/apache/fop/fo/FObj.java b/src/org/apache/fop/fo/FObj.java
new file mode 100644
index 000000000..a94cbcad6
--- /dev/null
+++ b/src/org/apache/fop/fo/FObj.java
@@ -0,0 +1,57 @@
+package org.apache.xml.fop.fo;
+
+// FOP
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+ * base class for representation of formatting objects and their processing
+ */
+public class FObj extends FONode {
+
+ public static class Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new FObj(parent, propertyList);
+ }
+ }
+
+ public static Maker maker() {
+ return new Maker();
+ }
+
+ protected PropertyList properties;
+ protected String name;
+
+ protected FObj(FObj parent, PropertyList propertyList) {
+ super(parent);
+ this.properties = propertyList;
+ this.name = "default FO";
+ }
+
+ protected void addCharacters(char data[], int start, int length) {
+ // ignore
+ }
+
+ public int layout(Area area) throws FOPException {
+ // should always be overridden
+ return OK;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ protected void start() {
+ // do nothing by default
+ }
+
+ protected void end() {
+ // do nothing by default
+ }
+}
+
diff --git a/src/org/apache/fop/fo/FObjMixed.java b/src/org/apache/fop/fo/FObjMixed.java
new file mode 100644
index 000000000..177e940b1
--- /dev/null
+++ b/src/org/apache/fop/fo/FObjMixed.java
@@ -0,0 +1,49 @@
+package org.apache.xml.fop.fo;
+
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.apps.FOPException;
+
+/**
+ * base class for representation of mixed content formatting objects
+ * and their processing
+ */
+public class FObjMixed extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new FObjMixed(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new FObjMixed.Maker();
+ }
+
+ protected FObjMixed(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ }
+
+ protected void addCharacters(char data[], int start, int length) {
+ children.addElement(new FOText(data,start,length,this));
+ }
+
+ public int layout(Area area) throws FOPException {
+
+ if (this.marker == START) {
+ this.marker = 0;
+ }
+
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ FONode fo = (FONode) children.elementAt(i);
+ int status;
+ if ((status = fo.layout(area)) != OK) {
+ this.marker = i;
+ return status;
+ }
+ }
+ return OK;
+ }
+}
+
diff --git a/src/org/apache/fop/fo/Makefile b/src/org/apache/fop/fo/Makefile
new file mode 100644
index 000000000..da4211088
--- /dev/null
+++ b/src/org/apache/fop/fo/Makefile
@@ -0,0 +1,33 @@
+
+
+BASEDIR:=../../../../..
+include $(BASEDIR)/Makefile.rules
+
+SUBDIRS=flow \
+ pagination
+
+
+SOURCES=FONode.java \
+ FOText.java \
+ FOTreeBuilder.java \
+ FObj.java \
+ FObjMixed.java \
+ Property.java \
+ PropertyList.java \
+ PropertyListBuilder.java \
+ StandardElementMapping.java
+
+CLASSES=$(SOURCES:.java=.class)
+
+all: $(CLASSES) allsubs
+
+clean: cleanme cleansubs
+
+cleanme:
+ rm -f *.class
+
+$(TARGETS:%=%subs): %subs :
+ for dir in $(SUBDIRS) ; do \
+ (cd $$dir && pwd && $(MAKE) $(MFLAGS) $*) || exit 1 ; \
+ done
+
diff --git a/src/org/apache/fop/fo/Property.java b/src/org/apache/fop/fo/Property.java
new file mode 100644
index 000000000..420bee8cb
--- /dev/null
+++ b/src/org/apache/fop/fo/Property.java
@@ -0,0 +1,41 @@
+package org.apache.xml.fop.fo;
+
+import org.apache.xml.fop.datatypes.*;
+import org.apache.xml.fop.apps.FOPException;
+
+public class Property {
+
+ public static class Maker {
+
+ public boolean isInherited() { return false; }
+
+ public Property make(PropertyList propertyList, String value) throws FOPException {
+ return null;
+ }
+
+ public Property make(PropertyList propertyList) throws FOPException { // default
+ return null;
+ }
+
+ public Property compute(PropertyList propertyList) { // compute
+ return null;
+ }
+ }
+ protected PropertyList propertyList;
+
+ public Length getLength() { return null; }
+ public String getString() { return null; }
+ public ColorType getColorType() { return null; }
+ public int getEnum() { return 0; }
+
+ public static double toDouble(String s) {
+ double d;
+ try {
+ d = Double.valueOf(s).doubleValue();
+ } catch (NumberFormatException e) {
+ d = Double.NaN;
+ }
+ return d;
+ }
+
+}
diff --git a/src/org/apache/fop/fo/PropertyList.java b/src/org/apache/fop/fo/PropertyList.java
new file mode 100644
index 000000000..e3a6092b7
--- /dev/null
+++ b/src/org/apache/fop/fo/PropertyList.java
@@ -0,0 +1,41 @@
+package org.apache.xml.fop.fo;
+
+import java.util.Hashtable;
+
+import org.apache.xml.fop.apps.FOPException;
+
+public class PropertyList extends Hashtable {
+ private PropertyListBuilder builder;
+ private PropertyList parentPropertyList = null;
+
+ public PropertyList(PropertyList parentPropertyList) {
+ this.parentPropertyList = parentPropertyList;
+ }
+
+ public Property get(String propertyName) {
+
+ if (builder == null)
+ System.err.println("OH OH, builder has not been set");
+ Property p = (Property)super.get(propertyName);
+
+ if (p == null) { // if not explicit
+ p = this.builder.computeProperty(this,propertyName);
+ if (p == null) { // else inherit
+ if ((this.parentPropertyList != null)&&(this.builder.isInherited(propertyName))) { // check for parent
+ p = this.parentPropertyList.get(propertyName); // retrieve parent's value
+ } else { // default
+ try {
+ p = this.builder.makeProperty(this,propertyName);
+ } catch (FOPException e) {
+ // don't know what to do here
+ }
+ }
+ }
+ }
+ return p;
+ }
+
+ public void setBuilder(PropertyListBuilder builder) {
+ this.builder = builder;
+ }
+}
diff --git a/src/org/apache/fop/fo/PropertyListBuilder.java b/src/org/apache/fop/fo/PropertyListBuilder.java
new file mode 100644
index 000000000..7c12763d6
--- /dev/null
+++ b/src/org/apache/fop/fo/PropertyListBuilder.java
@@ -0,0 +1,120 @@
+package org.apache.xml.fop.fo;
+
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.svg.*;
+
+import org.apache.xml.fop.apps.FOPException;
+
+import org.xml.sax.AttributeList;
+
+import java.util.Hashtable;
+
+public class PropertyListBuilder {
+ private Hashtable propertyTable;
+
+ public PropertyListBuilder() {
+ this.propertyTable = new Hashtable();
+
+ propertyTable.put("end-indent",EndIndent.maker());
+ propertyTable.put("page-master-name",PageMasterName.maker());
+ propertyTable.put("page-master-first",PageMasterFirst.maker());
+ propertyTable.put("page-master-repeating",PageMasterRepeating.maker());
+ propertyTable.put("page-master-odd",PageMasterOdd.maker());
+ propertyTable.put("page-master-even",PageMasterEven.maker());
+ propertyTable.put("margin-top",MarginTop.maker());
+ propertyTable.put("margin-bottom",MarginBottom.maker());
+ propertyTable.put("margin-left",MarginLeft.maker());
+ propertyTable.put("margin-right",MarginRight.maker());
+ propertyTable.put("extent",Extent.maker());
+ propertyTable.put("page-width",PageWidth.maker());
+ propertyTable.put("page-height",PageHeight.maker());
+ propertyTable.put("flow-name",FlowName.maker());
+ propertyTable.put("font-family",FontFamily.maker());
+ propertyTable.put("font-style",FontStyle.maker());
+ propertyTable.put("font-weight",FontWeight.maker());
+ propertyTable.put("font-size",FontSize.maker());
+ propertyTable.put("line-height",LineHeight.maker());
+ propertyTable.put("text-align",TextAlign.maker());
+ propertyTable.put("text-align-last",TextAlignLast.maker());
+ propertyTable.put("space-before.optimum",SpaceBeforeOptimum.maker());
+ propertyTable.put("space-after.optimum",SpaceAfterOptimum.maker());
+ propertyTable.put("start-indent",StartIndent.maker());
+ propertyTable.put("end-indent",EndIndent.maker());
+ propertyTable.put("provisional-distance-between-starts",ProvisionalDistanceBetweenStarts.maker());
+ propertyTable.put("provisional-label-separation",ProvisionalLabelSeparation.maker());
+ propertyTable.put("rule-thickness",RuleThickness.maker());
+ propertyTable.put("color",Color.maker());
+ propertyTable.put("wrap-option",WrapOption.maker());
+ propertyTable.put("white-space-treatment",WhiteSpaceTreatment.maker());
+ propertyTable.put("break-before",BreakBefore.maker());
+ propertyTable.put("break-after",BreakAfter.maker());
+ propertyTable.put("text-indent",TextIndent.maker());
+ propertyTable.put("href",HRef.maker());
+ propertyTable.put("column-width",ColumnWidth.maker());
+ propertyTable.put("height",SVGLength.maker());
+ propertyTable.put("width",SVGLength.maker());
+ propertyTable.put("x",SVGLength.maker());
+ propertyTable.put("y",SVGLength.maker());
+ propertyTable.put("x1",SVGLength.maker());
+ propertyTable.put("x2",SVGLength.maker());
+ propertyTable.put("y1",SVGLength.maker());
+ propertyTable.put("y2",SVGLength.maker());
+ }
+
+ public Property computeProperty(PropertyList propertyList, String propertyName) {
+
+ Property p = null;
+
+ Property.Maker propertyMaker = (Property.Maker)propertyTable.get(propertyName);
+ if (propertyMaker != null) {
+ p = propertyMaker.compute(propertyList);
+ } else {
+ //System.err.println("WARNING: property " + propertyName + " ignored");
+ }
+ return p;
+ }
+
+ public boolean isInherited(String propertyName) {
+ boolean b;
+
+ Property.Maker propertyMaker = (Property.Maker)propertyTable.get(propertyName);
+ if (propertyMaker != null) {
+ b = propertyMaker.isInherited();
+ } else {
+ //System.err.println("WARNING: Unknown property " + propertyName);
+ b = true;
+ }
+ return b;
+ }
+
+ public PropertyList makeList(AttributeList attributes, PropertyList parentPropertyList) throws FOPException {
+
+ PropertyList p = new PropertyList(parentPropertyList);
+ p.setBuilder(this);
+
+ for (int i = 0; i < attributes.getLength(); i++) {
+ String attributeName = attributes.getName(i);
+ Property.Maker propertyMaker = (Property.Maker)propertyTable.get(attributeName);
+ if (propertyMaker != null) {
+ p.put(attributeName,propertyMaker.make(p,attributes.getValue(i)));
+ } else {
+ //System.err.println("WARNING: property " + attributeName + " ignored");
+ }
+ }
+
+ return p;
+ }
+
+ public Property makeProperty(PropertyList propertyList, String propertyName) throws FOPException {
+
+ Property p = null;
+
+ Property.Maker propertyMaker = (Property.Maker)propertyTable.get(propertyName);
+ if (propertyMaker != null) {
+ p = propertyMaker.make(propertyList);
+ } else {
+ //System.err.println("WARNING: property " + propertyName + " ignored");
+ }
+ return p;
+ }
+}
diff --git a/src/org/apache/fop/fo/StandardElementMapping.java b/src/org/apache/fop/fo/StandardElementMapping.java
new file mode 100644
index 000000000..396b01aeb
--- /dev/null
+++ b/src/org/apache/fop/fo/StandardElementMapping.java
@@ -0,0 +1,52 @@
+package org.apache.xml.fop.fo;
+
+import org.apache.xml.fop.fo.flow.*;
+import org.apache.xml.fop.fo.pagination.*;
+
+public class StandardElementMapping implements ElementMapping {
+
+ public void addToBuilder(FOTreeBuilder builder) {
+
+ String uri = "http://www.w3.org/1999/XSL/Format";
+
+ builder.addMapping(uri, "root", Root.maker());
+ builder.addMapping(uri, "layout-master-set",
+ LayoutMasterSet.maker());
+ builder.addMapping(uri, "simple-page-master",
+ SimplePageMaster.maker());
+ builder.addMapping(uri, "region-body", RegionBody.maker());
+ builder.addMapping(uri, "region-before", RegionBefore.maker());
+ builder.addMapping(uri, "region-after", RegionAfter.maker());
+ builder.addMapping(uri, "page-sequence", PageSequence.maker());
+ builder.addMapping(uri, "sequence-specification",
+ SequenceSpecification.maker());
+ builder.addMapping(uri, "sequence-specifier-single",
+ SequenceSpecifierSingle.maker());
+ builder.addMapping(uri, "sequence-specifier-repeating",
+ SequenceSpecifierRepeating.maker());
+ builder.addMapping(uri, "sequence-specifier-alternating",
+ SequenceSpecifierAlternating.maker());
+ builder.addMapping(uri, "flow", Flow.maker());
+ builder.addMapping(uri, "static-content",
+ StaticContent.maker());
+ builder.addMapping(uri, "block", Block.maker());
+ builder.addMapping(uri, "list-block", ListBlock.maker());
+ builder.addMapping(uri, "list-item", ListItem.maker());
+ builder.addMapping(uri, "list-item-label",
+ ListItemLabel.maker());
+ builder.addMapping(uri, "list-item-body", ListItemBody.maker());
+ builder.addMapping(uri, "page-number", PageNumber.maker());
+ builder.addMapping(uri, "display-sequence",
+ DisplaySequence.maker());
+ builder.addMapping(uri, "inline-sequence",
+ InlineSequence.maker());
+ builder.addMapping(uri, "display-rule", DisplayRule.maker());
+ builder.addMapping(uri, "display-graphic",
+ DisplayGraphic.maker());
+ builder.addMapping(uri, "table", Table.maker());
+ builder.addMapping(uri, "table-column", TableColumn.maker());
+ builder.addMapping(uri, "table-body", TableBody.maker());
+ builder.addMapping(uri, "table-row", TableRow.maker());
+ builder.addMapping(uri, "table-cell", TableCell.maker());
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/Block.java b/src/org/apache/fop/fo/flow/Block.java
new file mode 100644
index 000000000..61e28108a
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/Block.java
@@ -0,0 +1,192 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.apps.FOPException;
+
+public class Block extends FObjMixed {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new Block(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new Block.Maker();
+ }
+
+ FontState fs;
+ int align;
+ int alignLast;
+ int breakBefore;
+ int breakAfter;
+ int lineHeight;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+ int textIndent;
+
+ BlockArea blockArea;
+
+ // this may be helpful on other FOs too
+ boolean anythingLaidOut = false;
+
+ public Block(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:block";
+ }
+
+ public int layout(Area area) throws FOPException {
+ // System.err.print(" b:LAY[" + marker + "] ");
+
+ if (this.marker == BREAK_AFTER) {
+ return OK;
+ }
+
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+ this.align = this.properties.get("text-align").getEnum();
+ this.alignLast =
+ this.properties.get("text-align-last").getEnum();
+ this.breakBefore =
+ this.properties.get("break-before").getEnum();
+ this.breakAfter =
+ this.properties.get("break-after").getEnum();
+ this.lineHeight =
+ this.properties.get("line-height").getLength().mvalue();
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+ this.textIndent =
+ this.properties.get("text-indent").getLength().mvalue();
+
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+ if (this.isInLabel) {
+ startIndent += bodyIndent;
+ endIndent += (area.getAllocationWidth()
+ - distanceBetweenStarts - startIndent)
+ + labelSeparation;
+ }
+
+ if (this.isInListBody) {
+ startIndent += bodyIndent + distanceBetweenStarts;
+ }
+
+ if (this.isInTableCell) {
+ startIndent += forcedStartOffset;
+ endIndent = area.getAllocationWidth() - startIndent -
+ forcedWidth;
+ }
+
+ this.marker = 0;
+
+ if (breakBefore == BreakBefore.PAGE) {
+ return FORCE_PAGE_BREAK;
+ }
+
+ if (breakBefore == BreakBefore.ODD_PAGE) {
+ return FORCE_PAGE_BREAK_ODD;
+ }
+
+ if (breakBefore == BreakBefore.EVEN_PAGE) {
+ return FORCE_PAGE_BREAK_EVEN;
+ }
+ }
+
+ if ((spaceBefore != 0) && (this.marker ==0)) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ if (anythingLaidOut) {
+ this.textIndent = 0;
+ }
+
+ this.blockArea =
+ new BlockArea(fs, area.getAllocationWidth(),
+ area.spaceLeft(), startIndent, endIndent,
+ textIndent, align, alignLast, lineHeight);
+ blockArea.setPage(area.getPage());
+ blockArea.start();
+
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ FONode fo = (FONode) children.elementAt(i);
+ if (this.isInListBody) {
+ fo.setIsInListBody();
+ fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ fo.setBodyIndent(this.bodyIndent);
+ }
+ int status;
+ if ((status = fo.layout(blockArea)) != OK) {
+ this.marker = i;
+ if ((i != 0) && (status == AREA_FULL_NONE)) {
+ status = AREA_FULL_SOME;
+ }
+ //blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+ anythingLaidOut = true;
+ return status;
+ }
+ anythingLaidOut = true;
+ }
+
+ blockArea.end();
+ area.addChild(blockArea);
+
+ /* should this be combined into above? */
+ area.increaseHeight(blockArea.getHeight());
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+
+ if (breakAfter == BreakAfter.PAGE) {
+ this.marker = BREAK_AFTER;
+ return FORCE_PAGE_BREAK;
+ }
+
+ if (breakAfter == BreakAfter.ODD_PAGE) {
+ this.marker = BREAK_AFTER;
+ return FORCE_PAGE_BREAK_ODD;
+ }
+
+ if (breakAfter == BreakAfter.EVEN_PAGE) {
+ this.marker = BREAK_AFTER;
+ return FORCE_PAGE_BREAK_EVEN;
+ }
+
+ //System.err.print(" b:OK" + marker + " ");
+ return OK;
+ }
+
+ public int getAreaHeight() {
+ return blockArea.getHeight();
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/DisplayGraphic.java b/src/org/apache/fop/fo/flow/DisplayGraphic.java
new file mode 100644
index 000000000..90f4508e5
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/DisplayGraphic.java
@@ -0,0 +1,132 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.BlockArea;
+import org.apache.xml.fop.layout.FontState;
+import org.apache.xml.fop.apps.FOPException;
+import org.apache.xml.fop.image.*;
+
+// Java
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+public class DisplayGraphic extends FObj {
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new DisplayGraphic(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new DisplayGraphic.Maker();
+ }
+
+ FontState fs;
+ int align;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+ String href;
+ int height;
+ int width;
+
+ ImageArea imageArea;
+
+ public DisplayGraphic(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:display-graphic";
+ }
+
+ public int layout(Area area) throws FOPException {
+
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+
+ // FIXME
+ this.align = this.properties.get("text-align").getEnum();
+
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+
+ this.href = this.properties.get("href").getString();
+ this.width =
+ this.properties.get("width").getLength().mvalue();
+ this.height =
+ this.properties.get("height").getLength().mvalue();
+
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ if (this.isInLabel) {
+ startIndent += bodyIndent;
+ endIndent += (area.getAllocationWidth()
+ - distanceBetweenStarts - startIndent)
+ + labelSeparation;
+ }
+
+ if (this.isInListBody) {
+ startIndent += bodyIndent + distanceBetweenStarts;
+ }
+
+ if (this.isInTableCell) {
+ startIndent += forcedStartOffset;
+ endIndent = area.getAllocationWidth() - startIndent -
+ forcedWidth;
+ }
+
+ this.marker = 0;
+ }
+
+ if ((spaceBefore != 0) && (this.marker == 0)) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ FopImage img = FopImageFactory.Make(href, 0, 0, width, height);
+
+ this.imageArea = new ImageArea(fs,
+ img,
+ area.getAllocationWidth(),
+ img.getWidth(),
+ img.getHeight(),
+ startIndent, endIndent,
+ align);
+
+ imageArea.start();
+ imageArea.end();
+ area.addChild(imageArea);
+ area.increaseHeight(imageArea.getHeight());
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/DisplayRule.java b/src/org/apache/fop/fo/flow/DisplayRule.java
new file mode 100644
index 000000000..83784816e
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/DisplayRule.java
@@ -0,0 +1,88 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.datatypes.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.BlockArea;
+import org.apache.xml.fop.layout.RuleArea;
+import org.apache.xml.fop.layout.FontState;
+import org.apache.xml.fop.apps.FOPException;
+
+public class DisplayRule extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new DisplayRule(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new DisplayRule.Maker();
+ }
+
+ public DisplayRule(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:display-rule";
+ }
+
+ public int layout(Area area) throws FOPException {
+ // FIXME: doesn't check to see if it will fit
+
+ String fontFamily = this.properties.get("font-family").getString();
+ String fontStyle = this.properties.get("font-style").getString();
+ String fontWeight = this.properties.get("font-weight").getString();
+ int fontSize = this.properties.get("font-size").getLength().mvalue();
+
+ FontState fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+
+ int align = this.properties.get("text-align").getEnum();
+ int startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ int endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ int spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ int spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+ int ruleThickness =
+ this.properties.get("rule-thickness").getLength().mvalue();
+ int ruleLength = 0; // not used;
+
+ ColorType c = this.properties.get("color").getColorType();
+ float red = c.red();
+ float green = c.green();
+ float blue = c.blue();
+
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ if (spaceBefore != 0) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ RuleArea ruleArea = new RuleArea(fs,
+ area.getAllocationWidth(),
+ area.spaceLeft(),
+ startIndent, endIndent,
+ align, ruleThickness,
+ ruleLength, red, green,
+ blue);
+ area.addChild(ruleArea);
+ area.increaseHeight(ruleArea.getHeight());
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/DisplaySequence.java b/src/org/apache/fop/fo/flow/DisplaySequence.java
new file mode 100644
index 000000000..c50b6bc6a
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/DisplaySequence.java
@@ -0,0 +1,52 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class DisplaySequence extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new DisplaySequence(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new DisplaySequence.Maker();
+ }
+
+ public DisplaySequence(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:display-sequence";
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == START) {
+ this.marker = 0;
+ }
+ // this is such common code, perhaps it should be in the super class
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ FObj fo = (FObj) children.elementAt(i);
+ int status;
+ if ((status = fo.layout(area)) != OK) {
+ /* message from child */
+ if (status > OK) {
+ /* child still successful */
+ this.marker = i+1;
+ } else {
+ /* child unsucessful */
+ this.marker = i;
+ }
+ return status;
+ }
+ }
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/Flow.java b/src/org/apache/fop/fo/flow/Flow.java
new file mode 100644
index 000000000..b9b66a1b8
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/Flow.java
@@ -0,0 +1,59 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.fo.pagination.PageSequence;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+public class Flow extends FObj {
+
+ 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 pageSequence;
+
+ protected Flow(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:flow";
+
+ 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());
+ }
+ pageSequence.setFlow(this);
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == START) {
+ this.marker = 0;
+ }
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ FObj fo = (FObj) children.elementAt(i);
+ int status;
+ if ((status = fo.layout(area)) != OK) {
+ this.marker = i;
+ return status;
+ }
+ }
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/InlineSequence.java b/src/org/apache/fop/fo/flow/InlineSequence.java
new file mode 100644
index 000000000..33efc6b31
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/InlineSequence.java
@@ -0,0 +1,35 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class InlineSequence extends FObjMixed {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new InlineSequence(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new InlineSequence.Maker();
+ }
+
+ public InlineSequence(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:inline-sequence";
+
+ if (parent.getName().equals("fo:flow")) {
+ throw new FOPException("inline-sequence can't be directly"
+ + " under flow");
+ }
+ }
+
+}
diff --git a/src/org/apache/fop/fo/flow/ListBlock.java b/src/org/apache/fop/fo/flow/ListBlock.java
new file mode 100644
index 000000000..6810825d5
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/ListBlock.java
@@ -0,0 +1,143 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.BlockArea;
+import org.apache.xml.fop.layout.FontState;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class ListBlock extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new ListBlock(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new ListBlock.Maker();
+ }
+
+ FontState fs;
+ int align;
+ int alignLast;
+ int breakBefore;
+ int breakAfter;
+ int lineHeight;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+ int provisionalDistanceBetweenStarts;
+ int provisionalLabelSeparation;
+ int spaceBetweenListRows = 0;
+
+ public ListBlock(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:list-block";
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+
+ this.align = this.properties.get("text-align").getEnum();
+ this.alignLast =
+ this.properties.get("text-align-last").getEnum();
+ this.lineHeight =
+ this.properties.get("line-height").getLength().mvalue();
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+ this.provisionalDistanceBetweenStarts =
+ this.properties.get("provisional-distance-between-starts").getLength().mvalue();
+ this.provisionalLabelSeparation =
+ this.properties.get("provisional-label-separation").getLength().mvalue();
+ this.spaceBetweenListRows = 0; // not used at present
+
+ this.marker = 0;
+
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ if (spaceBefore != 0) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ if (this.isInListBody) {
+ startIndent += bodyIndent + distanceBetweenStarts;
+ bodyIndent = startIndent;
+ }
+ }
+
+ BlockArea blockArea =
+ new BlockArea(fs, area.getAllocationWidth(),
+ area.spaceLeft(), startIndent, endIndent, 0,
+ align, alignLast, lineHeight);
+ blockArea.setPage(area.getPage());
+ blockArea.start();
+
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ if (!(children.elementAt(i) instanceof ListItem)) {
+ System.err.println("WARNING: This version of FOP requires list-items inside list-blocks");
+ return OK;
+ }
+ ListItem listItem = (ListItem) children.elementAt(i);
+ listItem.setDistanceBetweenStarts(this.provisionalDistanceBetweenStarts);
+ listItem.setLabelSeparation(this.provisionalLabelSeparation);
+ listItem.setBodyIndent(this.bodyIndent);
+ int status;
+ if ((status = listItem.layout(blockArea)) != OK) {
+ /* message from child */
+ if (status > OK) {
+ /* child still successful */
+ this.marker = i+1;
+ } else {
+ /* child unsucessful */
+ this.marker = i;
+ }
+ blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+ return status;
+ }
+ }
+
+ blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/ListItem.java b/src/org/apache/fop/fo/flow/ListItem.java
new file mode 100644
index 000000000..f69cf45da
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/ListItem.java
@@ -0,0 +1,144 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.BlockArea;
+import org.apache.xml.fop.layout.FontState;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class ListItem extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new ListItem(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new ListItem.Maker();
+ }
+
+ FontState fs;
+ int align;
+ int alignLast;
+ int breakBefore;
+ int breakAfter;
+ int lineHeight;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+
+ public ListItem(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:list-item";
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+
+ this.align = this.properties.get("text-align").getEnum();
+ this.alignLast =
+ this.properties.get("text-align-last").getEnum();
+ this.lineHeight =
+ this.properties.get("line-height").getLength().mvalue();
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+
+ this.marker = 0;
+ }
+
+ /* not sure this is needed given we know area is from list block */
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ if (spaceBefore != 0) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ startIndent += this.bodyIndent;
+
+ BlockArea blockArea =
+ new BlockArea(fs, area.getAllocationWidth(),
+ area.spaceLeft(), startIndent, endIndent,
+ 0, align, alignLast, lineHeight);
+ blockArea.setPage(area.getPage());
+ blockArea.start();
+
+ int numChildren = this.children.size();
+ if (numChildren != 2) {
+ throw new FOPException("list-item must have exactly two children");
+ }
+ ListItemLabel label = (ListItemLabel) children.elementAt(0);
+ ListItemBody body = (ListItemBody) children.elementAt(1);
+
+ label.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ label.setLabelSeparation(this.labelSeparation);
+ label.setBodyIndent(this.bodyIndent);
+
+ body.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ body.setBodyIndent(this.bodyIndent);
+
+ /* this doesn't actually do anything */
+ body.setLabelSeparation(this.labelSeparation);
+
+ int status;
+
+ // what follows doesn't yet take into account whether the
+ // body failed completely or only got some text in
+
+ if (this.marker == 0) {
+ status = label.layout(blockArea);
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ status = body.layout(blockArea);
+ if (status != OK) {
+ blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+ this.marker = 1;
+ return status;
+ }
+
+ blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ /* not sure this is needed given we know area is from list block */
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/ListItemBody.java b/src/org/apache/fop/fo/flow/ListItemBody.java
new file mode 100644
index 000000000..c348355f5
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/ListItemBody.java
@@ -0,0 +1,54 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.FontState;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class ListItemBody extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new ListItemBody(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new ListItemBody.Maker();
+ }
+
+ public ListItemBody(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:list-item-body";
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == START) {
+ this.marker = 0;
+ }
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ FObj fo = (FObj) children.elementAt(i);
+ fo.setIsInListBody();
+ fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ fo.setLabelSeparation(this.labelSeparation);
+ fo.setBodyIndent(this.bodyIndent);
+ int status;
+ if ((status = fo.layout(area)) != OK) {
+ this.marker = i;
+ if ((i == 0) && (status == AREA_FULL_NONE)) {
+ return AREA_FULL_NONE;
+ } else {
+ return AREA_FULL_SOME;
+ }
+ }
+ }
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/ListItemLabel.java b/src/org/apache/fop/fo/flow/ListItemLabel.java
new file mode 100644
index 000000000..fe7c0513a
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/ListItemLabel.java
@@ -0,0 +1,49 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.FontState;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class ListItemLabel extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new ListItemLabel(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new ListItemLabel.Maker();
+ }
+
+ public ListItemLabel(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:list-item-label";
+ }
+
+ public int layout(Area area) throws FOPException {
+ int numChildren = this.children.size();
+
+ if (numChildren != 1) {
+ throw new FOPException("list-item-label must have exactly one block in this version of FOP");
+ }
+ Block block = (Block) children.elementAt(0);
+
+ block.setIsInLabel();
+ block.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ block.setLabelSeparation(this.labelSeparation);
+ block.setBodyIndent(this.bodyIndent);
+
+ int status;
+ status = block.layout(area);
+ area.addDisplaySpace(-block.getAreaHeight());
+ return status;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/Makefile b/src/org/apache/fop/fo/flow/Makefile
new file mode 100644
index 000000000..72876ca68
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/Makefile
@@ -0,0 +1,39 @@
+
+
+BASEDIR:=../../../../../..
+include $(BASEDIR)/Makefile.rules
+
+SUBDIRS=
+
+
+SOURCES=Block.java \
+ DisplayGraphic.java \
+ DisplayRule.java \
+ DisplaySequence.java \
+ Flow.java \
+ InlineSequence.java \
+ ListBlock.java \
+ ListItemBody.java \
+ ListItemLabel.java \
+ PageNumber.java \
+ StaticContent.java \
+ Table.java \
+ TableBody.java \
+ TableCell.java \
+ TableColumn.java \
+ TableRow.java
+
+CLASSES=$(SOURCES:.java=.class)
+
+all: $(CLASSES) allsubs
+
+clean: cleanme cleansubs
+
+cleanme:
+ rm -f *.class
+
+$(TARGETS:%=%subs): %subs :
+ for dir in $(SUBDIRS) ; do \
+ (cd $$dir && pwd && $(MAKE) $(MFLAGS) $*) || exit 1 ; \
+ done
+
diff --git a/src/org/apache/fop/fo/flow/PageNumber.java b/src/org/apache/fop/fo/flow/PageNumber.java
new file mode 100644
index 000000000..3a3f59813
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/PageNumber.java
@@ -0,0 +1,66 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.datatypes.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class PageNumber extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new PageNumber(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new PageNumber.Maker();
+ }
+
+ FontState fs;
+ float red;
+ float green;
+ float blue;
+ int wrapOption;
+ int whiteSpaceTreatment;
+
+ public PageNumber(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:page-number";
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (!(area instanceof BlockArea)) {
+ System.err.println("WARNING: page-number outside block area");
+ return OK;
+ }
+ if (this.marker == START) {
+ String fontFamily = this.properties.get("font-family").getString();
+ String fontStyle = this.properties.get("font-style").getString();
+ String fontWeight = this.properties.get("font-weight").getString();
+ int fontSize = this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+
+ ColorType c = this.properties.get("color").getColorType();
+ this.red = c.red();
+ this.green = c.green();
+ this.blue = c.blue();
+
+ this.wrapOption = this.properties.get("wrap-option").getEnum();
+ this.whiteSpaceTreatment = this.properties.get("white-space-treatment").getEnum();
+
+ this.marker = 0;
+ }
+ String p = Integer.toString(area.getPage().getNumber());
+ this.marker = ((BlockArea) area).addText(fs, red, green, blue, wrapOption, whiteSpaceTreatment, p.toCharArray(), 0, p.length());
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/StaticContent.java b/src/org/apache/fop/fo/flow/StaticContent.java
new file mode 100644
index 000000000..5dc6971e1
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/StaticContent.java
@@ -0,0 +1,54 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.fo.pagination.PageSequence;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Enumeration;
+
+public class StaticContent extends FObj {
+
+ 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() {
+ 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 int layout(Area area) throws FOPException {
+ int numChildren = this.children.size();
+ for (int i = 0; i < numChildren; i++) {
+ FObj fo = (FObj) children.elementAt(i);
+ fo.layout(area);
+ }
+ resetMarker();
+ return OK;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/Table.java b/src/org/apache/fop/fo/flow/Table.java
new file mode 100644
index 000000000..f838a7947
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/Table.java
@@ -0,0 +1,183 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Vector;
+
+public class Table extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new Table(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new Table.Maker();
+ }
+
+ FontState fs;
+ int breakBefore;
+ int breakAfter;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+
+ Vector columns = new Vector();
+ int currentColumnNumber = 0;
+
+ BlockArea blockArea;
+
+ public Table(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:table";
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == BREAK_AFTER) {
+ return OK;
+ }
+
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+ this.breakBefore =
+ this.properties.get("break-before").getEnum();
+ this.breakAfter =
+ this.properties.get("break-after").getEnum();
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ if (this.isInListBody) {
+ startIndent += bodyIndent + distanceBetweenStarts;
+ }
+
+ this.marker = 0;
+
+ if (breakBefore == BreakBefore.PAGE) {
+ return FORCE_PAGE_BREAK;
+ }
+
+ if (breakBefore == BreakBefore.ODD_PAGE) {
+ return FORCE_PAGE_BREAK_ODD;
+ }
+
+ if (breakBefore == BreakBefore.EVEN_PAGE) {
+ return FORCE_PAGE_BREAK_EVEN;
+ }
+ }
+
+ if ((spaceBefore != 0) && (this.marker ==0)) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ this.blockArea =
+ new BlockArea(fs, area.getAllocationWidth(),
+ area.spaceLeft(), startIndent, endIndent, 0,
+ 0, 0, 0);
+ blockArea.setPage(area.getPage());
+ blockArea.start();
+
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ FONode fo = (FONode) children.elementAt(i);
+ if (fo instanceof TableColumn) {
+ TableColumn c = (TableColumn) fo;
+ int num = c.getColumnNumber();
+ if (num == 0) {
+ num = currentColumnNumber + 1;
+ }
+ currentColumnNumber = num;
+ if (num > columns.size()) {
+ columns.setSize(num);
+ }
+ columns.setElementAt(c, num-1);
+ } else if (fo instanceof TableBody) {
+ if (columns.size() == 0) {
+ System.err.println("WARNING: current implementation of tables requires a table-column for each column, indicating column-width");
+ return OK;
+ }
+
+ //if (this.isInListBody) {
+ //fo.setIsInListBody();
+ //fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ //fo.setBodyIndent(this.bodyIndent);
+ //}
+
+ ((TableBody) fo).setColumns(columns);
+
+ int status;
+ if ((status = fo.layout(blockArea)) != OK) {
+ this.marker = i;
+ if ((i != 0) && (status == AREA_FULL_NONE)) {
+ status = AREA_FULL_SOME;
+ }
+ //blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+ return status;
+ }
+ }
+ }
+
+ blockArea.end();
+ area.addChild(blockArea);
+
+ /* should this be combined into above? */
+ area.increaseHeight(blockArea.getHeight());
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+
+ if (breakAfter == BreakAfter.PAGE) {
+ this.marker = BREAK_AFTER;
+ return FORCE_PAGE_BREAK;
+ }
+
+ if (breakAfter == BreakAfter.ODD_PAGE) {
+ this.marker = BREAK_AFTER;
+ return FORCE_PAGE_BREAK_ODD;
+ }
+
+ if (breakAfter == BreakAfter.EVEN_PAGE) {
+ this.marker = BREAK_AFTER;
+ return FORCE_PAGE_BREAK_EVEN;
+ }
+
+ return OK;
+ }
+
+ public int getAreaHeight() {
+ return blockArea.getHeight();
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/TableBody.java b/src/org/apache/fop/fo/flow/TableBody.java
new file mode 100644
index 000000000..9ff6a842c
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/TableBody.java
@@ -0,0 +1,137 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Vector;
+
+public class TableBody extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new TableBody(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new TableBody.Maker();
+ }
+
+ FontState fs;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+
+ Vector columns;
+
+ BlockArea blockArea;
+
+ public TableBody(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:table-body";
+ }
+
+ public void setColumns(Vector columns) {
+ this.columns = columns;
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == BREAK_AFTER) {
+ return OK;
+ }
+
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ //if (this.isInListBody) {
+ //startIndent += bodyIndent + distanceBetweenStarts;
+ //}
+
+ this.marker = 0;
+
+ }
+
+ if ((spaceBefore != 0) && (this.marker ==0)) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ this.blockArea =
+ new BlockArea(fs, area.getAllocationWidth(),
+ area.spaceLeft(), startIndent, endIndent, 0,
+ 0, 0, 0);
+ blockArea.setPage(area.getPage());
+ blockArea.start();
+
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ TableRow row = (TableRow) children.elementAt(i);
+
+ //if (this.isInListBody) {
+ //fo.setIsInListBody();
+ //fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ //fo.setBodyIndent(this.bodyIndent);
+ //}
+
+ row.setColumns(columns);
+
+ int status;
+ if ((status = row.layout(blockArea)) != OK) {
+ this.marker = i;
+ if ((i != 0) && (status == AREA_FULL_NONE)) {
+ status = AREA_FULL_SOME;
+ }
+ //blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+ return status;
+ }
+ }
+
+ blockArea.end();
+ area.addChild(blockArea);
+
+ /* should this be combined into above? */
+ area.increaseHeight(blockArea.getHeight());
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+
+ return OK;
+ }
+
+ public int getAreaHeight() {
+ return blockArea.getHeight();
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/TableCell.java b/src/org/apache/fop/fo/flow/TableCell.java
new file mode 100644
index 000000000..f2df8328c
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/TableCell.java
@@ -0,0 +1,122 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.apps.FOPException;
+
+public class TableCell extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new TableCell(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new TableCell.Maker();
+ }
+
+ FontState fs;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+
+ protected int startOffset;
+ protected int width;
+ protected int height = 0;
+
+ BlockArea blockArea;
+
+ public TableCell(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:table-cell";
+ }
+
+ public void setStartOffset(int offset) {
+ startOffset = offset;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == BREAK_AFTER) {
+ return OK;
+ }
+
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ //if (this.isInListBody) {
+ //startIndent += bodyIndent + distanceBetweenStarts;
+ //}
+
+ this.marker = 0;
+
+ }
+
+ if ((spaceBefore != 0) && (this.marker ==0)) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ this.blockArea =
+ new BlockArea(fs, area.getAllocationWidth(),
+ area.spaceLeft(), startIndent, endIndent, 0,
+ 0, 0, 0);
+ blockArea.setPage(area.getPage());
+ blockArea.start();
+
+ int numChildren = this.children.size();
+ for (int i = this.marker; i < numChildren; i++) {
+ FObj fo = (FObj) children.elementAt(i);
+ fo.setIsInTableCell();
+ fo.forceStartOffset(startOffset);
+ fo.forceWidth(width);
+ int status;
+ if ((status = fo.layout(blockArea)) != OK) {
+ this.marker = i;
+ if ((i == 0) && (status == AREA_FULL_NONE)) {
+ return AREA_FULL_NONE;
+ } else {
+ return AREA_FULL_SOME;
+ }
+ }
+ height += blockArea.getHeight();
+
+ }
+ blockArea.end();
+ area.addChild(blockArea);
+
+ return OK;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/TableColumn.java b/src/org/apache/fop/fo/flow/TableColumn.java
new file mode 100644
index 000000000..6888bbef9
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/TableColumn.java
@@ -0,0 +1,34 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.apps.FOPException;
+
+public class TableColumn extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new TableColumn(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new TableColumn.Maker();
+ }
+
+ public TableColumn(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:table-column";
+ }
+
+ public int getColumnWidth() {
+ return this.properties.get("column-width").getLength().mvalue();
+ }
+
+ public int getColumnNumber() {
+ return 0; // not implemented yet
+ }
+}
diff --git a/src/org/apache/fop/fo/flow/TableRow.java b/src/org/apache/fop/fo/flow/TableRow.java
new file mode 100644
index 000000000..4f2f27a6a
--- /dev/null
+++ b/src/org/apache/fop/fo/flow/TableRow.java
@@ -0,0 +1,155 @@
+package org.apache.xml.fop.fo.flow;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.*;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Vector;
+
+public class TableRow extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new TableRow(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new TableRow.Maker();
+ }
+
+ FontState fs;
+ int startIndent;
+ int endIndent;
+ int spaceBefore;
+ int spaceAfter;
+
+ int widthOfCellsSoFar = 0;
+ int largestCellHeight = 0;
+
+ Vector columns;
+
+ BlockArea blockArea;
+
+ public TableRow(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ this.name = "fo:table-row";
+ }
+
+ public void setColumns(Vector columns) {
+ this.columns = columns;
+ }
+
+ public int layout(Area area) throws FOPException {
+ if (this.marker == BREAK_AFTER) {
+ return OK;
+ }
+
+ if (this.marker == START) {
+ String fontFamily =
+ this.properties.get("font-family").getString();
+ String fontStyle =
+ this.properties.get("font-style").getString();
+ String fontWeight =
+ this.properties.get("font-weight").getString();
+ int fontSize =
+ this.properties.get("font-size").getLength().mvalue();
+
+ this.fs = new FontState(area.getFontInfo(), fontFamily,
+ fontStyle, fontWeight, fontSize);
+ this.startIndent =
+ this.properties.get("start-indent").getLength().mvalue();
+ this.endIndent =
+ this.properties.get("end-indent").getLength().mvalue();
+ this.spaceBefore =
+ this.properties.get("space-before.optimum").getLength().mvalue();
+ this.spaceAfter =
+ this.properties.get("space-after.optimum").getLength().mvalue();
+ if (area instanceof BlockArea) {
+ area.end();
+ }
+
+ //if (this.isInListBody) {
+ //startIndent += bodyIndent + distanceBetweenStarts;
+ //}
+
+ this.marker = 0;
+
+ }
+
+ if ((spaceBefore != 0) && (this.marker ==0)) {
+ area.addDisplaySpace(spaceBefore);
+ }
+
+ this.blockArea =
+ new BlockArea(fs, area.getAllocationWidth(),
+ area.spaceLeft(), startIndent, endIndent, 0,
+ 0, 0, 0);
+ blockArea.setPage(area.getPage());
+ blockArea.start();
+
+ int numChildren = this.children.size();
+ if (numChildren != columns.size()) {
+ System.err.println("WARNING: Number of children under table-row not equal to number of table-columns");
+ return OK;
+ }
+
+ for (int i = this.marker; i < numChildren; i++) {
+ TableCell cell = (TableCell) children.elementAt(i);
+
+ //if (this.isInListBody) {
+ //fo.setIsInListBody();
+ //fo.setDistanceBetweenStarts(this.distanceBetweenStarts);
+ //fo.setBodyIndent(this.bodyIndent);
+ //}
+
+ cell.setStartOffset(widthOfCellsSoFar);
+ int width = ((TableColumn) columns.elementAt(i)).getColumnWidth();
+
+ cell.setWidth(width);
+ widthOfCellsSoFar += width;
+
+ int status;
+ if ((status = cell.layout(blockArea)) != OK) {
+ this.marker = i;
+ if ((i != 0) && (status == AREA_FULL_NONE)) {
+ status = AREA_FULL_SOME;
+ }
+ //blockArea.end();
+ area.addChild(blockArea);
+ area.increaseHeight(blockArea.getHeight());
+ return status;
+ }
+
+ int h = cell.getHeight();
+ blockArea.addDisplaySpace(-h);
+ if (h > largestCellHeight) {
+ largestCellHeight = h;
+ }
+
+ }
+
+ blockArea.end();
+ area.addChild(blockArea);
+ area.addDisplaySpace(largestCellHeight);
+ area.increaseHeight(largestCellHeight);
+
+ if (spaceAfter != 0) {
+ area.addDisplaySpace(spaceAfter);
+ }
+
+ if (area instanceof BlockArea) {
+ area.start();
+ }
+
+ return OK;
+ }
+
+ public int getAreaHeight() {
+ return blockArea.getHeight();
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/LayoutMasterSet.java b/src/org/apache/fop/fo/pagination/LayoutMasterSet.java
new file mode 100644
index 000000000..5e4d01dba
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/LayoutMasterSet.java
@@ -0,0 +1,50 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Hashtable;
+
+public class LayoutMasterSet extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new LayoutMasterSet(parent,propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new LayoutMasterSet.Maker();
+ }
+
+ private Hashtable layoutMasters;
+ private Root root;
+
+ protected LayoutMasterSet(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:layout-master-set";
+
+ this.layoutMasters = new Hashtable();
+ if (parent.getName().equals("fo:root")) {
+ this.root = (Root)parent;
+ root.setLayoutMasterSet(this);
+ } else {
+ throw
+ new FOPException("fo:layout-master-set must be child of fo:root, not "
+ + parent.getName());
+ }
+ }
+
+ protected void addLayoutMaster(String masterName, SimplePageMaster layoutMaster) {
+ this.layoutMasters.put(masterName, layoutMaster);
+ }
+
+ protected SimplePageMaster getLayoutMaster(String masterName) {
+ return (SimplePageMaster)this.layoutMasters.get(masterName);
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/Makefile b/src/org/apache/fop/fo/pagination/Makefile
new file mode 100644
index 000000000..ca1a2a346
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/Makefile
@@ -0,0 +1,36 @@
+
+
+BASEDIR:=../../../../../..
+include $(BASEDIR)/Makefile.rules
+
+SUBDIRS=
+
+
+SOURCES=LayoutMasterSet.java \
+ PageSequence.java \
+ RegionAfter.java \
+ RegionBefore.java \
+ RegionBody.java \
+ Root.java \
+ SequenceSpecification.java \
+ SequenceSpecifier.java \
+ SequenceSpecifierAlternating.java \
+ SequenceSpecifierRepeating.java \
+ SequenceSpecifierSingle.java \
+ SimplePageMaster.java
+
+
+CLASSES=$(SOURCES:.java=.class)
+
+all: $(CLASSES) allsubs
+
+clean: cleanme cleansubs
+
+cleanme:
+ rm -f *.class
+
+$(TARGETS:%=%subs): %subs :
+ for dir in $(SUBDIRS) ; do \
+ (cd $$dir && pwd && $(MAKE) $(MFLAGS) $*) || exit 1 ; \
+ done
+
diff --git a/src/org/apache/fop/fo/pagination/PageSequence.java b/src/org/apache/fop/fo/pagination/PageSequence.java
new file mode 100644
index 000000000..eaae6366d
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/PageSequence.java
@@ -0,0 +1,138 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.fo.flow.Flow;
+import org.apache.xml.fop.fo.flow.StaticContent;
+import org.apache.xml.fop.layout.Area;
+import org.apache.xml.fop.layout.AreaContainer;
+import org.apache.xml.fop.layout.AreaTree;
+import org.apache.xml.fop.layout.Page;
+import org.apache.xml.fop.layout.PageMaster;
+import org.apache.xml.fop.layout.PageMasterFactory;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class PageSequence extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new PageSequence(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new PageSequence.Maker();
+ }
+
+ protected Root root;
+ protected SequenceSpecification sequenceSpecification;
+ protected Flow flow;
+ protected StaticContent staticBefore;
+ protected StaticContent staticAfter;
+ protected LayoutMasterSet layoutMasterSet;
+
+ protected Page currentPage;
+ protected int currentPageNumber = 0;
+
+ protected PageSequence(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:page-sequence";
+
+ if (parent.getName().equals("fo:root")) {
+ this.root = (Root) parent;
+ this.root.addPageSequence(this);
+ } else {
+ throw
+ new FOPException("page-sequence must be child of root, not "
+ + parent.getName());
+ }
+ layoutMasterSet = root.getLayoutMasterSet();
+ }
+
+ protected Page makePage(AreaTree areaTree) throws FOPException {
+ PageMaster pageMaster;
+ // layout this page sequence
+
+ // while there is still stuff in the flow, ask the
+ // sequence-specification for a new page
+
+ if (this.sequenceSpecification == null) {
+ throw new FOPException("page-sequence is missing an"
+ + " sequence-specification");
+ }
+
+ PageMasterFactory pmf =
+ this.sequenceSpecification.getFirstPageMasterFactory();
+
+ pageMaster = pmf.getNextPageMaster();
+
+ while (pageMaster == null) {
+ /* move on to next sequence specifier */
+ pmf = pmf.getNext();
+ if (pmf == null) {
+ throw new FOPException("out of sequence specifiers"
+ + " (FOP will eventually allow this)");
+ }
+ pageMaster = pmf.getNextPageMaster();
+ }
+ return pageMaster.makePage(areaTree);
+ }
+
+ public void format(AreaTree areaTree) throws FOPException {
+ int status = OK;
+
+ do {
+ currentPage = makePage(areaTree);
+ currentPage.setNumber(++this.currentPageNumber);
+ System.err.print(" [" + currentPageNumber);
+ if ((this.staticBefore != null) &&
+ (currentPage.getBefore() != null)) {
+ AreaContainer beforeArea = currentPage.getBefore();
+ this.staticBefore.layout(beforeArea);
+ }
+ if ((this.staticAfter != null) &&
+ (currentPage.getAfter() != null)) {
+ AreaContainer afterArea = currentPage.getAfter();
+ this.staticAfter.layout(afterArea);
+ }
+ if ((status == FORCE_PAGE_BREAK_EVEN) &&
+ ((currentPageNumber % 2) == 1)) {
+ } else if ((status == FORCE_PAGE_BREAK_ODD) &&
+ ((currentPageNumber % 2) == 0)) {
+ } else {
+ AreaContainer bodyArea = currentPage.getBody();
+ status = this.flow.layout(bodyArea);
+ }
+ System.err.print("]");
+ areaTree.addPage(currentPage);
+ } while (status != OK);
+ System.err.println();
+ }
+
+ public void setFlow(Flow flow) {
+ this.flow = flow;
+ }
+
+ protected void setSequenceSpecification(SequenceSpecification sequenceSpecification) {
+ this.sequenceSpecification = sequenceSpecification;
+ sequenceSpecification.setLayoutMasterSet(this.layoutMasterSet);
+ }
+
+ public void setStaticContent(String name, StaticContent staticContent) {
+ if (name.equals("xsl-before")) {
+ this.staticBefore = staticContent;
+ } else if (name.equals("xsl-after")) {
+ this.staticAfter = staticContent;
+ } else {
+ System.err.println("WARNING: this version of FOP only supports "
+ + "static-content in region-before and region-after");
+ }
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/RegionAfter.java b/src/org/apache/fop/fo/pagination/RegionAfter.java
new file mode 100644
index 000000000..afac8fd1a
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/RegionAfter.java
@@ -0,0 +1,54 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Region;
+import org.apache.xml.fop.apps.FOPException;
+
+public class RegionAfter extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList) throws FOPException {
+ return new RegionAfter(parent,propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new RegionAfter.Maker();
+ }
+
+ SimplePageMaster layoutMaster;
+
+ protected RegionAfter(FObj parent, PropertyList propertyList)
+ 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,
+ int allocationRectangleYPosition,
+ int allocationRectangleWidth,
+ int allocationRectangleHeight) {
+ int marginTop = this.properties.get("margin-top").getLength().mvalue();
+ int marginBottom = this.properties.get("margin-bottom").getLength().mvalue();
+ int marginLeft = this.properties.get("margin-left").getLength().mvalue();
+ int marginRight = this.properties.get("margin-right").getLength().mvalue();
+ int extent = this.properties.get("extent").getLength().mvalue();
+
+ return new Region(allocationRectangleXPosition + marginLeft,
+ allocationRectangleYPosition -
+ allocationRectangleHeight + extent,
+ allocationRectangleWidth - marginLeft -
+ marginRight,extent);
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/RegionBefore.java b/src/org/apache/fop/fo/pagination/RegionBefore.java
new file mode 100644
index 000000000..79994d00f
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/RegionBefore.java
@@ -0,0 +1,53 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Region;
+import org.apache.xml.fop.apps.FOPException;
+
+public class RegionBefore extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList) throws FOPException {
+ return new RegionBefore(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new RegionBefore.Maker();
+ }
+
+ SimplePageMaster layoutMaster;
+
+ protected RegionBefore(FObj parent, PropertyList propertyList)
+ 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,
+ int allocationRectangleYPosition,
+ int allocationRectangleWidth,
+ int allocationRectangleHeight) {
+ int marginTop = this.properties.get("margin-top").getLength().mvalue();
+ int marginBottom = this.properties.get("margin-bottom").getLength().mvalue();
+ int marginLeft = this.properties.get("margin-left").getLength().mvalue();
+ int marginRight = this.properties.get("margin-right").getLength().mvalue();
+ int extent = this.properties.get("extent").getLength().mvalue();
+
+ return new Region(allocationRectangleXPosition + marginLeft,
+ allocationRectangleYPosition - marginTop,
+ allocationRectangleWidth - marginLeft -
+ marginRight, extent);
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/RegionBody.java b/src/org/apache/fop/fo/pagination/RegionBody.java
new file mode 100644
index 000000000..dfeaa880a
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/RegionBody.java
@@ -0,0 +1,50 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.Region;
+import org.apache.xml.fop.apps.FOPException;
+
+public class RegionBody extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList) throws FOPException {
+ return new RegionBody(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new RegionBody.Maker();
+ }
+
+ protected RegionBody(FObj parent, PropertyList propertyList)
+ 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,
+ int allocationRectangleYPosition,
+ int allocationRectangleWidth,
+ int allocationRectangleHeight) {
+ int marginTop = this.properties.get("margin-top").getLength().mvalue();
+ int marginBottom = this.properties.get("margin-bottom").getLength().mvalue();
+ int marginLeft = this.properties.get("margin-left").getLength().mvalue();
+ int marginRight = this.properties.get("margin-right").getLength().mvalue();
+
+ return new Region(allocationRectangleXPosition + marginLeft,
+ allocationRectangleYPosition - marginTop,
+ allocationRectangleWidth - marginLeft -
+ marginRight, allocationRectangleHeight -
+ marginTop - marginBottom);
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/Root.java b/src/org/apache/fop/fo/pagination/Root.java
new file mode 100644
index 000000000..ecfb42ba3
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/Root.java
@@ -0,0 +1,61 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.AreaTree;
+import org.apache.xml.fop.apps.FOPException;
+
+// Java
+import java.util.Vector;
+import java.util.Enumeration;
+
+public class Root extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new Root(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new Root.Maker();
+ }
+
+ LayoutMasterSet layoutMasterSet;
+ Vector pageSequences;
+
+ protected Root(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:root";
+
+ pageSequences = new Vector();
+ if (parent != null) {
+ throw new FOPException("root must be root element");
+ }
+ }
+
+ public void addPageSequence(PageSequence pageSequence) {
+ this.pageSequences.addElement(pageSequence);
+ }
+
+ public LayoutMasterSet getLayoutMasterSet() {
+ return this.layoutMasterSet;
+ }
+
+ public void format(AreaTree areaTree) throws FOPException {
+ if (layoutMasterSet == null) {
+ throw new FOPException("No layout master set.");
+ }
+ Enumeration e = pageSequences.elements();
+ while (e.hasMoreElements()) {
+ ((PageSequence) e.nextElement()).format(areaTree);
+ }
+ }
+
+ public void setLayoutMasterSet(LayoutMasterSet layoutMasterSet) {
+ this.layoutMasterSet = layoutMasterSet;
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/SequenceSpecification.java b/src/org/apache/fop/fo/pagination/SequenceSpecification.java
new file mode 100644
index 000000000..abea78aa0
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/SequenceSpecification.java
@@ -0,0 +1,66 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.PageMasterFactory;
+import org.apache.xml.fop.apps.FOPException;
+
+public class SequenceSpecification extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new SequenceSpecification(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new SequenceSpecification.Maker();
+ }
+
+ private PageSequence pageSequence;
+ private LayoutMasterSet layoutMasterSet;
+ private PageMasterFactory firstPMF;
+ private PageMasterFactory currentPMF;
+
+ protected SequenceSpecification(FObj parent,
+ PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:sequence-specification";
+
+ if (parent.getName().equals("fo:page-sequence")) {
+ this.pageSequence = (PageSequence) parent;
+ this.pageSequence.setSequenceSpecification(this);
+ } else {
+ throw new FOPException("sequence-specification must be child"
+ + " of page-sequence, not "
+ + parent.getName());
+ }
+ this.firstPMF = null;
+ this.currentPMF = null;
+
+}
+
+ protected void addSequenceSpecifier(SequenceSpecifier sequenceSpecifier) {
+ if (this.firstPMF == null) {
+ this.firstPMF = sequenceSpecifier.getPageMasterFactory();
+ } else {
+ this.currentPMF.setNext(sequenceSpecifier.getPageMasterFactory());
+ }
+ this.currentPMF = sequenceSpecifier.getPageMasterFactory();
+ }
+
+ protected PageMasterFactory getFirstPageMasterFactory() {
+ return this.firstPMF;
+ }
+
+ LayoutMasterSet getLayoutMasterSet() {
+ return this.layoutMasterSet;
+ }
+
+ protected void setLayoutMasterSet(LayoutMasterSet layoutMasterSet) {
+ this.layoutMasterSet = layoutMasterSet;
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/SequenceSpecifier.java b/src/org/apache/fop/fo/pagination/SequenceSpecifier.java
new file mode 100644
index 000000000..eef8433c5
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/SequenceSpecifier.java
@@ -0,0 +1,13 @@
+package org.apache.xml.fop.fo.pagination;
+
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.layout.PageMasterFactory;
+
+abstract public class SequenceSpecifier extends FObj {
+
+ protected SequenceSpecifier(FObj parent, PropertyList propertyList) {
+ super(parent, propertyList);
+ }
+
+ public abstract PageMasterFactory getPageMasterFactory();
+}
diff --git a/src/org/apache/fop/fo/pagination/SequenceSpecifierAlternating.java b/src/org/apache/fop/fo/pagination/SequenceSpecifierAlternating.java
new file mode 100644
index 000000000..f81bd1224
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/SequenceSpecifierAlternating.java
@@ -0,0 +1,65 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.PageMasterFactory;
+import org.apache.xml.fop.layout.AlternatingPageMasterFactory;
+import org.apache.xml.fop.layout.PageMaster;
+import org.apache.xml.fop.apps.FOPException;
+
+public class SequenceSpecifierAlternating extends SequenceSpecifier {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new SequenceSpecifierAlternating(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new SequenceSpecifierAlternating.Maker();
+ }
+
+ private SequenceSpecification sequenceSpecification;
+ private LayoutMasterSet layoutMasterSet;
+ private AlternatingPageMasterFactory pageMasterFactory;
+
+ protected SequenceSpecifierAlternating(FObj parent,
+ PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ PageMaster pf, pe, po;
+
+ this.name = "fo:sequence-specifer-alternating";
+
+ if (parent.getName().equals("fo:sequence-specification")) {
+ this.sequenceSpecification = (SequenceSpecification) parent;
+ this.layoutMasterSet = this.sequenceSpecification.getLayoutMasterSet();
+ } else {
+ throw new FOPException("fo:sequence-specifier-alternating must be "
+ + " child of fo:sequence-specification, not "
+ + parent.getName());
+ }
+
+ String pageMasterFirst = this.properties.get("page-master-first").getString();
+ String pageMasterOdd = this.properties.get("page-master-odd").getString();
+ String pageMasterEven = this.properties.get("page-master-even").getString();
+
+ try {
+ pf = this.layoutMasterSet.getLayoutMaster(pageMasterFirst).getPageMaster();
+ pe = this.layoutMasterSet.getLayoutMaster(pageMasterEven).getPageMaster();
+ po = this.layoutMasterSet.getLayoutMaster(pageMasterOdd).getPageMaster();
+ this.pageMasterFactory = new AlternatingPageMasterFactory(pf,pe,po);
+ } catch (java.lang.NullPointerException e) {
+ throw new FOPException("at least one of the page-master names in"
+ + " sequence-specifier-alternating is not in"
+ + " layout-master-set");
+ }
+ this.sequenceSpecification.addSequenceSpecifier(this);
+ }
+
+ public PageMasterFactory getPageMasterFactory() {
+ return this.pageMasterFactory;
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/SequenceSpecifierRepeating.java b/src/org/apache/fop/fo/pagination/SequenceSpecifierRepeating.java
new file mode 100644
index 000000000..1a5185137
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/SequenceSpecifierRepeating.java
@@ -0,0 +1,61 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.PageMasterFactory;
+import org.apache.xml.fop.layout.RepeatingPageMasterFactory;
+import org.apache.xml.fop.layout.PageMaster;
+import org.apache.xml.fop.apps.FOPException;
+
+public class SequenceSpecifierRepeating extends SequenceSpecifier {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new SequenceSpecifierRepeating(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new SequenceSpecifierRepeating.Maker();
+ }
+
+ private SequenceSpecification sequenceSpecification;
+ private LayoutMasterSet layoutMasterSet;
+ private RepeatingPageMasterFactory pageMasterFactory;
+
+ protected SequenceSpecifierRepeating(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ PageMaster pf, pr;
+
+ this.name = "fo:sequence-specifer-repeating";
+
+ if (parent.getName().equals("fo:sequence-specification")) {
+ this.sequenceSpecification = (SequenceSpecification) parent;
+ this.layoutMasterSet = this.sequenceSpecification.getLayoutMasterSet();
+ } else {
+ throw new FOPException("sequence-specifier-repeating must be "
+ + "child of fo:sequence-specification, "
+ + "not " + parent.getName());
+ }
+
+ String pageMasterFirst = this.properties.get("page-master-first").getString();
+ String pageMasterRepeating = this.properties.get("page-master-repeating").getString();
+ try {
+ pf = this.layoutMasterSet.getLayoutMaster(pageMasterFirst).getPageMaster();
+ pr = this.layoutMasterSet.getLayoutMaster(pageMasterRepeating).getPageMaster();
+ this.pageMasterFactory = new RepeatingPageMasterFactory(pf, pr);
+ } catch (java.lang.NullPointerException e) {
+ throw new FOPException("at least one of the page-master names in "
+ + "sequence-specifier-repeating is not in "
+ + "layout-master-set");
+ }
+ this.sequenceSpecification.addSequenceSpecifier(this);
+ }
+
+ public PageMasterFactory getPageMasterFactory() {
+ return this.pageMasterFactory;
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/SequenceSpecifierSingle.java b/src/org/apache/fop/fo/pagination/SequenceSpecifierSingle.java
new file mode 100644
index 000000000..bb46eff2f
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/SequenceSpecifierSingle.java
@@ -0,0 +1,59 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.PageMasterFactory;
+import org.apache.xml.fop.layout.SinglePageMasterFactory;
+import org.apache.xml.fop.layout.PageMaster;
+import org.apache.xml.fop.apps.FOPException;
+
+public class SequenceSpecifierSingle extends SequenceSpecifier {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new SequenceSpecifierSingle(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new SequenceSpecifierSingle.Maker();
+ }
+
+ private SequenceSpecification sequenceSpecification;
+ private LayoutMasterSet layoutMasterSet;
+ private SinglePageMasterFactory pageMasterFactory;
+
+ protected SequenceSpecifierSingle(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:sequence-specifer-single";
+
+ if (parent.getName().equals("fo:sequence-specification")) {
+ this.sequenceSpecification = (SequenceSpecification) parent;
+ this.layoutMasterSet = this.sequenceSpecification.getLayoutMasterSet();
+ } else {
+ throw new FOPException("sequence-specifier-single must be "
+ + "child of fo:sequence-specification, "
+ + "not " + parent.getName());
+ }
+
+ String pageMasterName = this.properties.get("page-master-name").getString();
+ try {
+ this.pageMasterFactory = new SinglePageMasterFactory(this.layoutMasterSet.getLayoutMaster(pageMasterName).getPageMaster());
+ } catch (java.lang.NullPointerException e) {
+ throw new FOPException("page-master-name " +
+ pageMasterName + " must be in layout-master-set");
+ }
+ this.sequenceSpecification.addSequenceSpecifier(this);
+ }
+
+ public PageMasterFactory getPageMasterFactory() {
+ return this.pageMasterFactory;
+ }
+
+ public String getPageMasterName() {
+ return this.properties.get("page-master-name").getString();
+ }
+}
diff --git a/src/org/apache/fop/fo/pagination/SimplePageMaster.java b/src/org/apache/fop/fo/pagination/SimplePageMaster.java
new file mode 100644
index 000000000..7f0a38841
--- /dev/null
+++ b/src/org/apache/fop/fo/pagination/SimplePageMaster.java
@@ -0,0 +1,89 @@
+package org.apache.xml.fop.fo.pagination;
+
+// FOP
+import org.apache.xml.fop.fo.*;
+import org.apache.xml.fop.fo.properties.*;
+import org.apache.xml.fop.layout.PageMaster;
+import org.apache.xml.fop.layout.Region;
+import org.apache.xml.fop.apps.FOPException;
+
+public class SimplePageMaster extends FObj {
+
+ public static class Maker extends FObj.Maker {
+ public FObj make(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ return new SimplePageMaster(parent, propertyList);
+ }
+ }
+
+ public static FObj.Maker maker() {
+ return new SimplePageMaster.Maker();
+ }
+
+ RegionBody regionBody;
+ RegionBefore regionBefore;
+ RegionAfter regionAfter;
+
+ LayoutMasterSet layoutMasterSet;
+ PageMaster pageMaster;
+
+ protected SimplePageMaster(FObj parent, PropertyList propertyList)
+ throws FOPException {
+ super(parent, propertyList);
+ this.name = "fo:simple-page-master";
+
+ if (parent.getName().equals("fo:layout-master-set")) {
+ this.layoutMasterSet = (LayoutMasterSet) parent;
+ String pm = this.properties.get("page-master-name").getString();
+ if (pm == null) {
+ System.err.println("WARNING: simple-page-master does not have "
+ + "a page-master-name and so is being ignored");
+ } else {
+ this.layoutMasterSet.addLayoutMaster(pm, this);
+ }
+ } else {
+ throw new FOPException("fo:simple-page-master must be child "
+ + "of fo:layout-master-set, not "
+ + parent.getName());
+ }
+ }
+
+ protected void end() {
+ int pageWidth = this.properties.get("page-width").getLength().mvalue();
+ int pageHeight = this.properties.get("page-height").getLength().mvalue();
+
+ int marginTop = this.properties.get("margin-top").getLength().mvalue();
+ int marginBottom = this.properties.get("margin-bottom").getLength().mvalue();
+ int marginLeft = this.properties.get("margin-left").getLength().mvalue();
+ int marginRight = this.properties.get("margin-right").getLength().mvalue();
+
+ int contentRectangleXPosition = marginLeft;
+ int contentRectangleYPosition = pageHeight - marginTop;
+ int contentRectangleWidth = pageWidth - marginLeft - marginRight;
+ 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));
+ }
+
+ PageMaster getPageMaster() {
+ return this.pageMaster;
+ }
+
+ protected void setRegionAfter(RegionAfter region) {
+ this.regionAfter = region;
+ }
+
+ protected void setRegionBefore(RegionBefore region) {
+ this.regionBefore = region;
+ }
+
+ protected void setRegionBody(RegionBody region) {
+ this.regionBody = region;
+ }
+}