]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
First versions of LayoutManager classes
authorKaren Lease <klease@apache.org>
Fri, 9 Nov 2001 21:57:47 +0000 (21:57 +0000)
committerKaren Lease <klease@apache.org>
Fri, 9 Nov 2001 21:57:47 +0000 (21:57 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194539 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/layoutmgr/AbstractLayoutManager.java [new file with mode: 0644]
src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java [new file with mode: 0644]
src/org/apache/fop/layoutmgr/BreakCost.java [new file with mode: 0644]
src/org/apache/fop/layoutmgr/FlowLayoutManager.java [new file with mode: 0644]
src/org/apache/fop/layoutmgr/LayoutManager.java [new file with mode: 0644]
src/org/apache/fop/layoutmgr/PageLayoutManager.java [new file with mode: 0644]
src/org/apache/fop/layoutmgr/SpaceSpecifier.java [new file with mode: 0644]
src/org/apache/fop/layoutmgr/SplitContext.java [new file with mode: 0644]

diff --git a/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/org/apache/fop/layoutmgr/AbstractLayoutManager.java
new file mode 100644 (file)
index 0000000..d09ca9c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.area.Area;
+
+import java.util.Iterator;
+
+/**
+ * The base class for all LayoutManagers.
+ */
+public abstract class AbstractLayoutManager implements LayoutManager {
+    protected LayoutManager parentLM;
+    protected FObj fobj;
+
+
+    public AbstractLayoutManager(FObj fobj) {
+       this.fobj = fobj;
+       this.parentLM = null;
+    }
+
+    public void setParentLM(LayoutManager lm) {
+       this.parentLM = lm;
+    }
+
+
+    /**
+     * Propagates to lower level layout managers. It iterates over the
+     * children of its FO, asks each for its LayoutManager and calls
+     * its generateAreas method.
+     */
+    public void generateAreas() {
+       Iterator children = fobj.getChildren();
+       while (children.hasNext()) {
+           LayoutManager lm = ((FObj)children.next()).getLayoutManager();
+           lm.setParentLM(this);
+           if (lm != null) {
+               lm.generateAreas();
+           }
+       }
+       flush(); // Add last area to parent
+    }
+
+//     /**
+//      * Ask the parent LayoutManager to add the current (full) area to the
+//      * appropriate parent area.
+//      * @param bFinished If true, this area is finished, either because it's
+//      * completely full or because there is no more content to put in it.
+//      * If false, we are in the middle of this area. This can happen,
+//      * for example, if we find floats in a line. We stop the current area,
+//      * and add it (temporarily) to its parent so that we can see if there
+//      * is enough space to place the float(s) anchored in the line.
+//      */
+//     protected void flush(Area area, boolean bFinished) {
+//     if (area != null) {
+//         // area.setFinished(true);
+//         parentLM.addChild(area, bFinished); // ????
+//         if (bFinished) {
+//             setCurrentArea(null);
+//         }
+//     }
+//     }
+
+    /** 
+     * Force current area to be added to parent area.
+     */
+    abstract protected void flush();
+
+
+    /**
+     * Return an Area which can contain the passed childArea. The childArea
+     * may not yet have any content, but it has essential traits set.
+     * In general, if the LayoutManager already has an Area it simply returns
+     * it. Otherwise, it makes a new Area of the appropriate class.
+     * It gets a parent area for its area by calling its parent LM.
+     * Finally, based on the dimensions of the parent area, it initializes
+     * its own area. This includes setting the content IPD and the maximum
+     * BPD.
+     */
+    abstract public Area getParentArea(Area childArea);
+
+
+    public boolean generatesInlineAreas() {
+       return false;
+    }
+
+    public boolean generatesLineAreas() {
+       return false;
+    }
+
+    /**
+     * Add a child area to the current area. If this causes the maximum
+     * dimension of the current area to be exceeded, the parent LM is called
+     * to add it.
+     */
+    abstract public void addChild(Area childArea) ;
+
+    /** Do nothing */
+    public boolean splitArea(Area areaToSplit, SplitContext context) {
+       context.nextArea = areaToSplit;
+       return false;
+    }
+
+}
diff --git a/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
new file mode 100644 (file)
index 0000000..8a550b9
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.BlockParent;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.MinOptMax;
+
+import java.util.Iterator;
+
+/**
+ * Base LayoutManager class for all areas which stack their child
+ * areas in the block-progression direction, such as Flow, Block, ListBlock.
+ */
+public abstract class BlockStackingLayoutManager 
+    extends AbstractLayoutManager {
+    /** Reference to FO whose areas it's managing or to the traits
+     * of the FO.
+     */
+    LayoutManager curChildLM = null;
+    BlockParent parentArea = null;
+
+    public BlockStackingLayoutManager(FObj fobj) {
+       super(fobj);
+    }
+
+
+
+    public boolean splitArea(Area area, SplitContext splitContext) {
+       // Divide area so that it will be within targetLength if possible
+       // If not, it can be shorter, but not longer.
+       /* Iterate over contents of the area. */
+       
+       // Need to figure out if we can do this generically
+       // Logically a BlockStacking LM only handles Block-type areas
+       if (!(area instanceof BlockParent)) {
+           return false;
+       }
+       Iterator areaIter = ((BlockParent)area).getChildAreas().iterator();
+       
+
+       BreakCost minBreakCost = null;
+       MinOptMax remainBPD = splitContext.targetBPD;
+       splitContext.nextArea = area;
+
+       while (areaIter.hasNext()) {
+           Area childArea = (Area)areaIter.next();
+           if (remainBPD.max < childArea.getAllocationBPD().min) {
+               // Past the end point: try to break it
+               // TODO: get a LayoutManager to do the split of the child
+               // area, either Area => LM or Area => gen FO => LM
+               LayoutManager childLM = childArea.getGeneratingFObj().
+                   getLayoutManager();
+               splitContext.targetBPD = remainBPD;
+               if (childLM.splitArea(childArea, splitContext) == false) {
+                   // Can't split, so must split this area before childArea
+                   // Can we pass the iter?
+                   // If already saw several a potential break, use it
+                   if (minBreakCost != null) {
+                       /* Split 'area', placing all children after
+                        * minBreakCost.getArea() into a new area,
+                        * which we store in the splitContext.
+                        */
+                       // splitContext.nextArea = area.splitAfter(minBreakCost.getArea());
+                   }
+                   else {
+                       /* This area will be shorter than the desired minimum.
+                        * Split before the current childArea (which will be
+                        * the first area in the newly created Area.
+                        */
+                       //splitContext.nextArea = area.splitBefore(childArea);
+                   }
+               }
+               else return true; // childLM has done the work for us!
+               // Set cost, dimension ???
+               break;
+           }
+           else {
+               remainBPD.subtract(childArea.getAllocationBPD());
+               if (remainBPD.min < 0) {
+                   // Potential breakpoint: remember break Position and
+                   // break "cost" (constraint violation)
+                   BreakCost breakCost = evaluateBreakCost(area, childArea);
+                   minBreakCost = breakCost.chooseLowest(minBreakCost);
+               }
+           }
+           //Note: size of area when split can depend on conditional
+           // space, border and padding of the split area!!!
+       }
+       // True if some part of area can be placed, false if none is placed
+       return (splitContext.nextArea != area);
+       
+    }
+
+    private BreakCost evaluateBreakCost(Area parent, Area child) {
+       return new BreakCost(child,0);
+    }
+
+    /** return current area being filled 
+     */
+    protected BlockParent getCurrentArea() {
+       return this.parentArea;
+    }
+
+
+    /** 
+     * Set the current area being filled.
+     */
+    protected void setCurrentArea(BlockParent parentArea) {
+       this.parentArea = parentArea;
+    }
+
+
+
+    protected MinOptMax resolveSpaceSpecifier(Area nextArea) {
+       SpaceSpecifier spaceSpec = new SpaceSpecifier();
+//     Area prevArea = getCurrentArea().getLast();
+//     if (prevArea != null) {
+//         spaceSpec.addSpace(prevArea.getSpaceAfter());
+//     }
+//     spaceSpec.addSpace(nextArea.getSpaceBefore());
+       return spaceSpec.resolve();
+    }
+
+    /**
+     * Add the childArea to the passed area.
+     * Called by child LayoutManager when it has filled one of its areas.
+     * The LM should already have an Area in which to put the child.
+     * See if the area will fit in the current area.
+     * If so, add it. Otherwise initiate breaking.
+     * @param childArea the area to add: will be some block-stacked Area.
+     * @param parentArea the area in which to add the childArea
+     */
+    protected void addChildToArea(Area childArea, BlockParent parentArea) {
+       // This should be a block-level Area (Block in the generic sense)
+       if (!(childArea instanceof Block)) {
+           System.err.println("Child not a Block in BlockStackingLM!");
+           return;
+       }
+
+       // See if the whole thing fits, including space before
+       // Calculate space between last child in curFlow and childArea
+       MinOptMax targetDim = parentArea.getAvailBPD();
+       MinOptMax spaceBefore = resolveSpaceSpecifier(childArea) ;
+       targetDim.subtract(spaceBefore);
+       if (targetDim.max >= childArea.getAllocationBPD().min) {
+           //parentArea.addBlock(new InterBlockSpace(spaceBefore));
+           parentArea.addBlock((Block)childArea);
+           return;
+       }
+       else {
+           // Probably need something like max BPD so we don't get into
+           // infinite loops with large unbreakable chunks
+           SplitContext splitContext = new SplitContext(targetDim);
+
+           LayoutManager childLM = childArea.getGeneratingFObj().
+                   getLayoutManager();
+           if (childLM.splitArea(childArea, splitContext)) {
+               //parentArea.addBlock(new InterBlockSpace(spaceBefore));
+               parentArea.addBlock((Block)childArea);
+           }
+           flush(); // hand off current area to parent
+           getParentArea(splitContext.nextArea);
+           // Check that reference IPD hasn't changed!!!
+           // If it has, we must "reflow" the content
+           addChild(splitContext.nextArea);
+       }
+    }
+
+
+    /**
+     * Add the childArea to the current area.
+     * Called by child LayoutManager when it has filled one of its areas.
+     * The LM should already have an Area in which to put the child.
+     * See if the area will fit in the current area.
+     * If so, add it. Otherwise initiate breaking.
+     * @param childArea the area to add: will be some block-stacked Area.
+     */
+    public void addChild(Area childArea) {
+       addChildToArea((Block)childArea, getCurrentArea());
+    }
+
+    /** 
+     * Force current area to be added to parent area.
+     */
+    protected void flush() {
+       parentLM.addChild(getCurrentArea());
+    }
+
+
+}
diff --git a/src/org/apache/fop/layoutmgr/BreakCost.java b/src/org/apache/fop/layoutmgr/BreakCost.java
new file mode 100644 (file)
index 0000000..66d513f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.area.Area;
+
+
+/**
+ * Evaluate and store the cost of breaking an Area at a given point.
+ */
+public class BreakCost {
+    private Area breakArea;
+
+    private int cost; // Will be more complicated than this!
+
+    public BreakCost(Area breakArea, int cost) {
+       this.breakArea = breakArea;
+       this.cost = cost;
+    }
+
+    Area getArea() {
+       return breakArea;
+    }
+
+    public BreakCost chooseLowest(BreakCost otherCost) {
+       return this;
+    }
+}
diff --git a/src/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/org/apache/fop/layoutmgr/FlowLayoutManager.java
new file mode 100644 (file)
index 0000000..f68d693
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.properties.Constants;
+import org.apache.fop.area.*;
+
+/**
+ * LayoutManager for an fo:flow object.
+ * Its parent LM is the PageLayoutManager.
+ * This LM is responsible for getting columns of the appropriate size
+ * and filling them with block-level areas generated by its children.
+ */
+public class FlowLayoutManager extends BlockStackingLayoutManager {
+
+    /** Array of areas currently being filled stored by area class */
+    private BlockParent[] currentAreas = new BlockParent[Area.CLASS_MAX];
+
+    /**
+     * This is the top level layout manager.
+     * It is created by the PageSequence FO.
+     */
+    public FlowLayoutManager(FObj fobj) {
+       super(fobj);
+    }
+
+
+
+    /**
+     * Add child area to a the correct container, depending on its
+     * area class. A Flow can fill at most one area container of any class
+     * at any one time. The actual work is done by BlockStackingLM.
+     */
+    public void addChild(Area childArea) {
+       addChildToArea(childArea,
+                      this.currentAreas[childArea.getAreaClass()]);
+    }
+
+    public Area getParentArea(Area childArea) {
+       // Get an area from the Page
+       BlockParent parentArea =
+           (BlockParent)parentLM.getParentArea(childArea);
+       this.currentAreas[parentArea.getAreaClass()] = parentArea;
+       setCurrentArea(parentArea);
+       return parentArea;
+    }
+
+
+}
diff --git a/src/org/apache/fop/layoutmgr/LayoutManager.java b/src/org/apache/fop/layoutmgr/LayoutManager.java
new file mode 100644 (file)
index 0000000..078e118
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+
+import org.apache.fop.area.Area;
+
+/**
+ * The interface for all LayoutManagers.
+ */
+public interface LayoutManager {
+    public void generateAreas();
+    public Area getParentArea (Area childArea);
+    public void addChild (Area childArea);
+    public boolean splitArea(Area areaToSplit, SplitContext context);
+    public void setParentLM(LayoutManager lm);
+}
diff --git a/src/org/apache/fop/layoutmgr/PageLayoutManager.java b/src/org/apache/fop/layoutmgr/PageLayoutManager.java
new file mode 100644 (file)
index 0000000..a38c5d3
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.area.*;
+import org.apache.fop.fo.pagination.PageSequence;
+import org.apache.fop.fo.properties.Constants;
+
+/**
+ * LayoutManager for a PageSequence and its flow.
+ * It manages all page-related layout.
+ */
+public class PageLayoutManager extends AbstractLayoutManager
+  implements Runnable{
+
+    private PageSequence pageseq;
+    /** True if haven't yet laid out any pages.*/
+    private boolean bFirstPage;
+    /** Current page being worked on. */
+    private PageViewport curPage;
+
+    /** Body region of the current page */
+    private BodyRegion curBody;
+
+    /** Current span being filled */
+    private Span curSpan;
+
+    /** Number of columns in current span area. */
+    private int curSpanColumns;
+
+
+    /** Current flow-reference-area (column) being filled. */
+    private Flow curFlow;
+
+    /** Manager which handles a queue of all pages which are completely
+     * laid out and ready for rendering, except for resolution of ID
+     * references?
+     */
+    private AreaTree areaTree;
+
+    /**
+     * This is the top level layout manager.
+     * It is created by the PageSequence FO.
+     */
+    public PageLayoutManager(AreaTree areaTree, PageSequence pageseq) {
+       super( pageseq);
+       this.areaTree = areaTree;
+    }
+
+
+    /** 
+     * The layout process is designed to be able to be run in a thread.
+     * In theory it can run at the same
+     * time as FO tree generation, once the layout-master-set has been read.
+     * We can arrange it so that the iterator over the fobj children waits
+     * until the next child is available.
+     * As it produces pages, it adds them to the AreaTree, where the
+     * rendering process can also run in a parallel thread.
+     */
+    public void run() {
+       generateAreas();
+    }
+
+
+    /**
+     * For now, only handle normal flow areas.
+     */
+    public void addChild(Area childArea) {
+       if (childArea.getAreaClass() == Area.CLASS_NORMAL) {
+           placeFlowRefArea(childArea);
+       }
+       else ; // TODO: all the others!
+    }
+
+    /**
+     * Place a FlowReferenceArea into the current span. The FlowLM is
+     * responsible for making sure that it will actually fit in the
+     * current span area. In fact the area has already been added to the
+     * current span, so we are just checking to see if the span is "full",
+     * possibly moving to the next column or to the next page.
+     */
+    protected void placeFlowRefArea(Area area) {
+       // assert (curSpan != null);
+       // assert (area == curFlow);
+       // assert (curFlow == curSpan.getFlow(curSpan.getColumnCount()-1));
+       // assert (area.getBPD().min < curSpan.getHeight());
+       // Last column on this page is filled
+       // See if the flow is full. The Flow LM can add an area before
+       // it's full in the case of a break or a span.
+       // Also in the case of a float to be placed. In that case, there
+       // may be further material added later.
+       // The Flow LM sets the "finished" flag on the Flow Area if it has
+       // completely filled it. In this case, if on the last column
+       // end the page.
+
+       // Alternatively the child LM indicates to parent that it's full?
+       if (area.getAllocationBPD().max >= curSpan.getMaxBPD().min) {
+           // Consider it filled
+           if (curSpan.getColumnCount() == curSpanColumns) {
+               finishPage();
+           }
+           else curFlow = null; // Create new flow on next getParentArea()
+       }
+    }
+
+
+    protected void placeAbsoluteArea(Area area) {
+    }
+
+
+    protected void placeBeforeFloat(Area area) {
+    }
+
+
+    protected void placeSideFloat(Area area) {
+    }
+
+    protected void placeFootnote(Area area) {
+       // After doing this, reduce available space on the curSpan.
+       // This has to be propagated to the curFlow (FlowLM) so that
+       // it can adjust its limit for composition (or it just asks
+       // curSpan for BPD before doing the break?)
+       // If multi-column, we may have to balance to find more space
+       // for a float. When?
+    }
+
+
+
+     private PageViewport makeNewPage(boolean bIsBlank, boolean bIsLast) {
+       finishPage();
+       try {
+           curPage = pageseq.createPage(bIsBlank, bIsLast);
+       } catch (FOPException fopex) { /* ???? */ }
+       curBody = (BodyRegion) curPage.getPage().
+           getRegion(RegionReference.BODY).getRegion();
+       return curPage;
+     }
+
+    private void finishPage() {
+       if (curPage != null) {
+           // Layout static content into the regions
+           // Need help from pageseq for this
+           // Queue for ID resolution and rendering
+           areaTree.addPage(curPage);
+           curPage = null;
+           curBody = null;
+           curSpan=null;
+           curFlow=null;
+       }
+    }
+
+    /**
+     * This is called from FlowLayoutManager when it needs to start
+     * a new flow container (while generating areas).
+     * @param area The area for which a container is needed. It must be
+     * some kind of block-level area. It must have area-class, break-before
+     * and span properties set.
+     */
+    public Area getParentArea(Area childArea) {
+       int aclass = childArea.getAreaClass() ;
+       if (aclass == Area.CLASS_NORMAL) {
+           // TODO: how to get properties from the Area???
+           // Need span, break
+           int breakVal = Constants.AUTO; // childArea.getBreakBefore();
+           if (breakVal != Constants.AUTO) {
+               // We may be forced to make new page
+               handleBreak(breakVal);
+           }
+           else if (curPage == null) {
+               makeNewPage(false, false);
+           }
+           // Now we should be on the right kind of page
+           boolean bNeedSpan = false;
+           int span = Constants.NONE; // childArea.getSpan()
+           int numCols=1;
+           if (span == Constants.ALL) {
+               // Assume the number of columns is stored on the curBody object.
+               //numCols = curBody.getProperty(NUMBER_OF_COLUMNS);
+           }
+           if (curSpan == null) {
+               createBodyMainReferenceArea();
+               bNeedSpan = true;
+           }
+           else if (numCols != curSpanColumns) {
+               // TODO: BALANCE EXISTING COLUMNS
+               if (curSpanColumns > 1) {
+                   // balanceColumns();
+               }
+               bNeedSpan = true;
+           }
+           if (bNeedSpan) {
+               // Make a new span and the first flow
+               createSpan(numCols);
+           }
+           else if (curFlow == null) {
+               createFlow();
+           }
+           return curFlow;
+       }
+       else {
+           if (curPage == null) {
+               makeNewPage(false, false);
+           }
+           // Now handle different kinds of areas
+           if (aclass == Area.CLASS_BEFORE_FLOAT) {
+               BeforeFloat bf = curBody.getBeforeFloat();
+               if (bf == null) {
+                   bf = new BeforeFloat();
+                   curBody.setBeforeFloat(bf);
+               }
+               return bf;
+           }
+           else if (aclass == Area.CLASS_FOOTNOTE) {
+               Footnote fn = curBody.getFootnote();
+               if (fn == null) {
+                   fn = new Footnote();
+                   curBody.setFootnote(fn);
+               }
+               return fn;
+           }
+           // TODO!!! other area classes (side-float, absolute, fixed)
+           return null;
+       }
+    }
+
+
+    /**
+     * Depending on the kind of break condition, make new column
+     * or page. May need to make an empty page if next page would
+     * not have the desired "handedness".
+     */
+    protected void handleBreak(int breakVal) {
+       if (breakVal == Constants.COLUMN) {
+           if (curSpan != null &&
+                curSpan.getColumnCount() != curSpanColumns) {
+               // Move to next column
+               createFlow();
+               return;
+           }
+           // else need new page
+           breakVal = Constants.PAGE;
+       }
+       if (needEmptyPage(breakVal)) {
+           curPage = makeNewPage(true, false);
+       }
+       if (needNewPage(breakVal)) {
+           curPage = makeNewPage(false, false);
+       }
+    }
+
+
+    /**
+     * If we have already started to layout content on a page,
+     * and there is a forced break, see if we need to generate
+     * an empty page.
+     * Note that if not all content is placed, we aren't sure whether
+     * it will flow onto another page or not, so we'd probably better
+     * block until the queue of layoutable stuff is empty!
+     */
+    private boolean needEmptyPage(int breakValue) {
+       return false;
+//     if (breakValue == Constants.PAGE || curPage.isEmpty()) {
+//         // any page is OK or we already have an empty page
+//         return false;
+//     }
+//     else {
+//         /* IF we are on the kind of page we need, we'll need a new page. */
+//         if (curPage.getPageNumber()%2 != 0) {
+//             // Current page is odd
+//             return (breakValue == Constants.ODD_PAGE);
+//         }
+//         else {
+//             return (breakValue == Constants.EVEN_PAGE);
+//         }
+//     }
+    }
+    
+    /**
+     * See if need to generate a new page for a forced break condition.
+     * TODO: methods to see if the current page is empty and to get
+     * its number.
+     */
+    private boolean needNewPage(int breakValue) {
+       return false;
+//     if (curPage.isEmpty()) {
+//         if (breakValue == Constants.PAGE) {
+//             return false;
+//         }
+//         else if (curPage.getPageNumber()%2 != 0) {
+//             // Current page is odd
+//             return (breakValue == Constants.EVEN_PAGE);
+//         }
+//         else {
+//             return (breakValue == Constants.ODD_PAGE);
+//         }
+//     }
+//     else {
+//         return true;
+//     }
+    }
+
+
+    private void createBodyMainReferenceArea() {
+       curBody.setMainReference(new MainReference());
+    }
+
+
+
+    private Flow createFlow() {
+       curFlow = new Flow();
+       // Set IPD and max BPD on the curFlow from curBody
+       curSpan.addFlow(curFlow);
+       return curFlow;
+    }
+
+    private void createSpan(int numCols) {
+       // check number of columns (= all in Body or 1)
+       // If already have a span, get its size and position (as MinMaxOpt)
+       // This determines the position of the new span area
+       // Attention: space calculation between the span areas.
+       
+//     MinOptMax newpos ;
+//     if (curSpan != null) {
+//         newpos = curSpan.getPosition(BPD);
+//         newpos.add(curSpan.getDimension(BPD));
+//     }
+//     else newpos = new MinOptMax();
+       curSpan =  new Span(numCols);
+       //curSpan.setPosition(BPD, newpos);
+       curBody.getMainReference().addSpan(curSpan);
+       createFlow();
+    }
+
+    // See finishPage...
+    protected void flush() {}
+
+}
diff --git a/src/org/apache/fop/layoutmgr/SpaceSpecifier.java b/src/org/apache/fop/layoutmgr/SpaceSpecifier.java
new file mode 100644 (file)
index 0000000..ca33c07
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.area.Area;
+import org.apache.fop.area.MinOptMax;
+import org.apache.fop.datatypes.Space;
+
+
+/**
+ * Accumulate a sequence of space-specifiers (XSL space type) on
+ * areas with a stacking constraint. Provide a way to resolve these into
+ * a single MinOptMax value.
+ */
+public class SpaceSpecifier {
+
+    /**
+     * Combine passed space property value with any existing space.
+     */
+    public void addSpace(Space moreSpace) {
+    }
+
+    public MinOptMax resolve() {
+       return new MinOptMax();
+    }
+}
diff --git a/src/org/apache/fop/layoutmgr/SplitContext.java b/src/org/apache/fop/layoutmgr/SplitContext.java
new file mode 100644 (file)
index 0000000..d798af5
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.fop.area.Area;
+import org.apache.fop.area.MinOptMax;
+
+public class SplitContext {
+
+    Area nextArea;
+    MinOptMax targetBPD;
+
+    public SplitContext(MinOptMax targetBPD) {
+       this.targetBPD = targetBPD;
+       nextArea = null;
+    }
+
+}